Phone Harness
ShawnPana/phone-harness
Control the user's phone — an iPhone through the Mac's iPhone Mirroring window, an Android over adb, or a rented cloud Android: open apps, tap, type, swipe, read the screen.
A skill your agent uses to migrate a codebase off the deprecated android.test.
$ npx skills add skydoves/android-testing-skills --skill migrating-from-android-test-classes -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install skydoves/android-testing-skills migrating-from-android-test-classes --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/skydoves/android-testing-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/platform/legacy/migrating-from-android-test-classes .claude/skills/migrating-from-android-test-classes && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "migrating-from-android-test-classes" agent skill from https://github.com/skydoves/android-testing-skills/tree/main/platform/legacy/migrating-from-android-test-classes into .claude/skills/migrating-from-android-test-classes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "migrating-from-android-test-classes", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/skydoves/android-testing-skills/tree/main/platform/legacy/migrating-from-android-test-classesType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add skydoves/android-testing-skills --skill migrating-from-android-test-classes -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install skydoves/android-testing-skills migrating-from-android-test-classes --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/skydoves/android-testing-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/platform/legacy/migrating-from-android-test-classes .agents/skills/migrating-from-android-test-classes && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "migrating-from-android-test-classes" agent skill from https://github.com/skydoves/android-testing-skills/tree/main/platform/legacy/migrating-from-android-test-classes into .agents/skills/migrating-from-android-test-classes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "migrating-from-android-test-classes", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add skydoves/android-testing-skills --skill migrating-from-android-test-classes -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install skydoves/android-testing-skills migrating-from-android-test-classes --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/skydoves/android-testing-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/platform/legacy/migrating-from-android-test-classes .cursor/skills/migrating-from-android-test-classes && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "migrating-from-android-test-classes" agent skill from https://github.com/skydoves/android-testing-skills/tree/main/platform/legacy/migrating-from-android-test-classes into .cursor/skills/migrating-from-android-test-classes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "migrating-from-android-test-classes", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/skydoves/android-testing-skills.git --path platform/legacy/migrating-from-android-test-classes--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add skydoves/android-testing-skills --skill migrating-from-android-test-classes -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install skydoves/android-testing-skills migrating-from-android-test-classes --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/skydoves/android-testing-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/platform/legacy/migrating-from-android-test-classes .gemini/skills/migrating-from-android-test-classes && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "migrating-from-android-test-classes" agent skill from https://github.com/skydoves/android-testing-skills/tree/main/platform/legacy/migrating-from-android-test-classes into .gemini/skills/migrating-from-android-test-classes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "migrating-from-android-test-classes", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install skydoves/android-testing-skills migrating-from-android-test-classesInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add skydoves/android-testing-skills --skill migrating-from-android-test-classes -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/skydoves/android-testing-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/platform/legacy/migrating-from-android-test-classes .github/skills/migrating-from-android-test-classes && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "migrating-from-android-test-classes" agent skill from https://github.com/skydoves/android-testing-skills/tree/main/platform/legacy/migrating-from-android-test-classes into .github/skills/migrating-from-android-test-classes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "migrating-from-android-test-classes", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add skydoves/android-testing-skills --skill migrating-from-android-test-classes -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install skydoves/android-testing-skills migrating-from-android-test-classes --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/skydoves/android-testing-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/platform/legacy/migrating-from-android-test-classes .opencode/skills/migrating-from-android-test-classes && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "migrating-from-android-test-classes" agent skill from https://github.com/skydoves/android-testing-skills/tree/main/platform/legacy/migrating-from-android-test-classes into .opencode/skills/migrating-from-android-test-classes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "migrating-from-android-test-classes", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
migrating-from-android-test-classesA skill your agent uses to migrate a codebase off the deprecated android.test.
Migrating From Android Test Classes is an agent skill from skydoves/android-testing-skills. Use this skill to migrate a codebase off the deprecated android.test. testing classes that ship in the Android platform SDK onto AndroidX Test. Covers InstrumentationTestRunner → AndroidJUnitRunner; InstrumentationTestCase/AndroidTestCase → @RunWith(AndroidJUnit4) + InstrumentationRegistry/ApplicationProvider; ActivityInstrumentationTestCase2 → ActivityScenario/ActivityScenarioRule + Espresso; ServiceTestCase/ProviderTestCase2 → ServiceTestRule/ProviderTestRule; MoreAsserts → Truth/Hamcrest…
Its SKILL.md is about 5.3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Mobile, covering Mobile testing and debugging. It works with Android. The repository describes itself as: ⚡️ A set of skills for Android testing: Compose UI, AndroidX Test, JVM unit tests, and ADB. The licence is Apache-2.0.
Read from SKILL.md and the folder at commit 8665ed5. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Migrating From Android Test Classes loads about 5.3k tokens when it runs. Until then it costs about 261 tokens; SKILL.md has 1,357 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from skydoves/android-testing-skills at commit 8665ed5, republished under its Apache-2.0 licence (© skydoves). 1,357 words, ~5,348 tokens.
.claude/skills/migrating-from-android-test-classes/SKILL.md (or your agent's skills folder).The android.test.* package shipped in the Android SDK (InstrumentationTestCase, ActivityInstrumentationTestCase2, AndroidTestCase, ServiceTestCase, MoreAsserts, TouchUtils, android.test.mock.*, …) is @Deprecated — the platform's own Javadoc routes every class to AndroidX Test. Old codebases still carry these, and they actively hold back JUnit4, Espresso, ActivityScenario, and the AndroidX runner. This skill is the class-by-class replacement map and the mechanical migration patterns.
android.test.InstrumentationTestCase / AndroidTestCase / ActivityInstrumentationTestCase2 / ServiceTestCase / MoreAsserts / ViewAsserts / TouchUtils / android.test.mock.* as @Deprecated.testInstrumentationRunner is android.test.InstrumentationTestRunner and tests behave oddly under AndroidJUnitRunner (or won't be discovered).getInstrumentation() outside a TestCase", "getActivity() / setActivityIntent() without ActivityInstrumentationTestCase2", "getContext() without AndroidTestCase".junit.framework.TestCase (JUnit3 style: setUp() override, testFoo() naming, assertEquals from junit.framework.Assert) and the team wants JUnit4.MoreAsserts.assertContentsInAnyOrder / assertEquals(int[], int[]) / assertContainsRegex, ViewAsserts.assertOnScreen, TouchUtils.tapView/dragQuarterScreenDown, or android.test.suitebuilder.annotation.SmallTest.ActivityScenario, Espresso, ServiceTestRule) — go straight to ../../../instrumentation/runner/running-instrumented-tests-with-androidjunit4/SKILL.md, ../../../instrumentation/scenarios/launching-activities-with-activityscenario/SKILL.md, ../../../instrumentation/espresso/writing-espresso-tests/SKILL.md.kotlin.test assertions (assertEquals, assertFailsWith) — use ../../../kotlin/kotlin-test/writing-tests-with-kotlin-test/SKILL.md. (kotlin.test is one valid target for MoreAsserts calls.)TestCase in pure-JVM code — for the JVM/Robolectric side use ../../../jvm-tests/robolectric/using-robolectric-correctly/SKILL.md and ../../../jvm-tests/runner/configuring-junit4-on-android/SKILL.md.android.test.* at all; use the AndroidX skills directly.../../../instrumentation/runner/running-instrumented-tests-with-androidjunit4/SKILL.md for the exact coordinate matrix (androidx.test:core, :runner, :rules, androidx.test.ext:junit). For host/JVM tests, ../../../jvm-tests/runner/configuring-junit4-on-android/SKILL.md.junit:junit:4.13.2 or via kotlin("test")). The legacy classes are JUnit3-shaped (extends TestCase); the migration target is JUnit4 (@Test + @RunWith).androidx.test.espresso:espresso-core) for anything that was using TouchUtils / ViewAsserts / ActivityInstrumentationTestCase2's UI poking.Legacy android.test.* (deprecated) | Use instead | Notes |
|---|---|---|
InstrumentationTestRunner (the testInstrumentationRunner) | androidx.test.runner.AndroidJUnitRunner | Change android.defaultConfig.testInstrumentationRunner. The legacy runner does not run JUnit4 or Espresso correctly. |
InstrumentationTestCase | @RunWith(AndroidJUnit4::class) + InstrumentationRegistry.getInstrumentation() | getInstrumentation() → androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(). injectInstrumentation(...) is gone. sendKeys/runTestOnUiThread → getInstrumentation().runOnMainSync { … } or @UiThreadTest. |
AndroidTestCase | @RunWith(AndroidJUnit4::class) + ApplicationProvider.getApplicationContext() | getContext() → ApplicationProvider.getApplicationContext<Context>(). getTestContext() (the test APK's context) → InstrumentationRegistry.getInstrumentation().context. |
ApplicationTestCase<T> | @RunWith(AndroidJUnit4::class), drive Application via ApplicationProvider.getApplicationContext() | No 1:1 base class — the Application is just a context now; assert on it directly. |
ActivityInstrumentationTestCase2<T>, ActivityUnitTestCase<T>, SingleLaunchActivityTestCase<T> | ActivityScenario<T> / @get:Rule ActivityScenarioRule<T> (+ Espresso for UI) | getActivity() → scenario.onActivity { activity -> … }. setActivityIntent(intent) → ActivityScenario.launch<T>(intent). getInstrumentation().waitForIdleSync() → Espresso's automatic sync. See ../../../instrumentation/scenarios/launching-activities-with-activityscenario/SKILL.md. |
| (Fragment cases, if any home-grown) | FragmentScenario / launchFragmentInContainer | ../../../instrumentation/scenarios/launching-fragments-with-fragmentscenario/SKILL.md. |
ServiceTestCase<T> | androidx.test.rule.ServiceTestRule | startService(intent) / bindService(intent) move onto the rule (@get:Rule val serviceRule = ServiceTestRule()); getService() → the IBinder from serviceRule.bindService(intent). |
ProviderTestCase2<T> | androidx.test.rule.provider.ProviderTestRule | ProviderTestCase2 is the JUnit3-shaped form; ProviderTestRule.Builder(MyProvider::class.java, AUTHORITY).build() is the JUnit4 way and still gives an isolated ContentResolver. |
LoaderTestCase | (Loaders are themselves deprecated) | Migrate the Loader to a ViewModel + coroutines/Flow first, then test that with runTest / Turbine. |
MoreAsserts (assertContentsInAnyOrder, assertEquals(int[], int[]), assertEmpty, assertNotEqual, assertContainsRegex, checkEqualsAndHashCodeMethods) | Google Truth (assertThat(list).containsExactly(...), .isEmpty(), .containsMatch(regex)), Hamcrest, or kotlin.test.assertContentEquals for ordered arrays | The platform Javadoc says "use Hamcrest"; Truth reads better. androidx.test.ext:truth ships Android-specific Truth subjects. |
ViewAsserts (assertOnScreen, assertHorizontalCenterAligned, assertBottomAligned, …) | Espresso ViewMatchers + ViewAssertions (matches(isCompletelyDisplayed()), layout-relation custom matchers) | See ../../../instrumentation/espresso/writing-espresso-tests/SKILL.md. |
TouchUtils (tapView, clickView, longClickView, dragQuarterScreenDown, scrollToBottom, dragViewToTop) | Espresso ViewActions (click(), longClick(), swipeUp()/swipeDown(), scrollTo(), GeneralSwipeAction) | The legacy methods need a live Instrumentation + Activity reference; Espresso actions run inside onView(...).perform(...). |
android.test.UiThreadTest | androidx.test.annotation.UiThreadTest | Just change the import; or replace with getInstrumentation().runOnMainSync { … } / scenario.onActivity { … } (which is already on the main thread). |
android.test.FlakyTest | androidx.test.filters.FlakyTest | Import change. |
android.test.suitebuilder.annotation.SmallTest / MediumTest / LargeTest / Suppress | androidx.test.filters.SmallTest / MediumTest / LargeTest / Suppress | Import change; the runner reads -e size small against the AndroidX annotations. |
android.test.InstrumentationTestSuite, android.test.suitebuilder.TestSuiteBuilder | JUnit4 @RunWith(Suite::class) + @Suite.SuiteClasses([...]), or just let AndroidJUnitRunner discover by @SmallTest/package | Manual suite building is rarely needed once the AndroidX runner is in place. |
android.test.mock.MockContext | A real context (ApplicationProvider.getApplicationContext()), or Robolectric's context on the JVM, or mock(Context::class.java) (Mockito/MockK) for tight isolation | MockContext throws UnsupportedOperationException from almost every method — it was a hand-stubbing base, which a mocking framework does better. |
android.test.mock.MockContentResolver + MockContentProvider | ProviderTestRule (isolated resolver), or a real ContentResolver from a Robolectric/instrumented context | If you genuinely need a stub resolver, Mockito a ContentResolver. |
android.test.mock.MockPackageManager | Mockito/MockK mock(PackageManager::class.java) | The platform Javadoc explicitly says "use a mocking framework like Mockito". |
android.test.mock.MockResources / MockCursor / MockDialogInterface / MockApplication / MockService | Mockito/MockK mocks, or real instances from a test context | Same story — these were stub bases, mocking frameworks supersede them. |
android.test.AndroidTestRunner, android.test.PerformanceTestCase, android.test.RepetitiveTest | AndroidJUnitRunner; androidx.benchmark (Microbenchmark/Macrobenchmark); a custom JUnit4 @Rule or just a loop | PerformanceTestCase predates androidx.benchmark — real perf testing belongs there. |
extends junit.framework.TestCase + assertEquals from junit.framework.Assert (JUnit3 shape) | @RunWith(AndroidJUnit4::class) + @Test methods + org.junit.Assert.* / kotlin.test.* | Method names no longer need a test prefix; setUp/tearDown overrides become @Before/@After (or @BeforeTest/@AfterTest). |
The platform's own
@deprecatedJavadoc often points at the old "Android Testing Support Library" /android.support.test.*names (e.g.ActivityTestRule). Those becameandroidx.test.*, and several have since been re-deprecated again —ActivityTestRule→ActivityScenario. Migrate to the current target in the table above, not to whatever the platform Javadoc literally says.
1. Flip the runner first. Set android.defaultConfig.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" and add the AndroidX Test deps. Until this is done, JUnit4/Espresso/ActivityScenario cannot run. (../../../instrumentation/runner/running-instrumented-tests-with-androidjunit4/SKILL.md.)
2. Convert one test class at a time, JUnit3 → JUnit4. Drop extends …TestCase, add @RunWith(AndroidJUnit4::class), annotate test methods @Test, convert setUp()/tearDown() overrides to @Before/@After (no super call), and rename testFoo → foo if you like. Replace each legacy accessor with its AndroidX equivalent from the table.
3. Replace base-class superpowers with explicit AndroidX entry points. getContext() → ApplicationProvider.getApplicationContext(); getInstrumentation() → InstrumentationRegistry.getInstrumentation(); getActivity() → ActivityScenario + onActivity { }; getService() → ServiceTestRule.bindService(...).
4. Swap the assertion helpers. MoreAsserts.* → Truth/kotlin.test; ViewAsserts.* → Espresso ViewAssertions; TouchUtils.* → Espresso ViewActions.
5. Swap the mock contexts. Anything extending android.test.mock.MockContext/MockResources/MockPackageManager → a real test context where possible, otherwise a Mockito/MockK mock. (../../../jvm-tests/mocking/mocking-with-mockito/SKILL.md.)
6. Delete the legacy imports and confirm nothing references android.test.* or android.test.mock.* any more. A clean module compiles with zero import android.test. lines.
ActivityInstrumentationTestCase2 → ActivityScenario// WRONG — deprecated base class
class LoginActivityTest : ActivityInstrumentationTestCase2<LoginActivity>(LoginActivity::class.java) {
fun testTitleShown() {
val activity = activity // getActivity()
assertEquals("Sign in", activity.title)
}
}
// WRONG because: android.test.ActivityInstrumentationTestCase2 is @Deprecated; it ties the test to
// the legacy InstrumentationTestRunner, blocks JUnit4/Espresso, and getActivity() leaks the Activity
// off the main thread.// RIGHT — ActivityScenario + JUnit4
@RunWith(AndroidJUnit4::class)
class LoginActivityTest {
@get:Rule val scenario = ActivityScenarioRule(LoginActivity::class.java)
@Test fun titleShown() {
scenario.scenario.onActivity { activity ->
assertEquals("Sign in", activity.title)
}
onView(withId(R.id.title)).check(matches(withText("Sign in"))) // or assert via Espresso
}
}AndroidTestCase → @RunWith(AndroidJUnit4) + ApplicationProvider// WRONG
class FormatterTest : AndroidTestCase() {
fun testCurrency() {
val s = CurrencyFormatter(context).format(1099) // getContext()
assertEquals("$10.99", s)
}
}
// WRONG because: android.test.AndroidTestCase is @Deprecated; getContext() and the TestCase shape
// are the legacy world.// RIGHT
@RunWith(AndroidJUnit4::class)
class FormatterTest {
private val context: Context = ApplicationProvider.getApplicationContext()
@Test fun currency() {
assertEquals("$10.99", CurrencyFormatter(context).format(1099))
}
}MoreAsserts / TouchUtils calls// WRONG
MoreAsserts.assertContentsInAnyOrder(ids, 3L, 1L, 2L) // android.test.MoreAsserts (deprecated)
TouchUtils.tapView(this, listView) // android.test.TouchUtils (deprecated)
ViewAsserts.assertOnScreen(rootView, listView) // android.test.ViewAsserts (deprecated)// RIGHT
assertThat(service.ids()).containsExactly(1L, 2L, 3L) // Google Truth (order-insensitive)
onView(withId(R.id.list)).perform(click()) // Espresso ViewActions
onView(withId(R.id.list)).check(matches(isCompletelyDisplayed())) // Espresso ViewAssertionsandroid.test.mock.MockContext subclass → real context or Mockito// WRONG
class FakeContext : MockContext() { // android.test.mock.MockContext (deprecated)
override fun getPackageName() = "com.example"
// every other method throws UnsupportedOperationException
}// RIGHT — a real test context if the SUT just reads from it
val context: Context = ApplicationProvider.getApplicationContext()
// RIGHT — a mock if you must control specific calls in isolation
val context = mock<Context> { on { packageName } doReturn "com.example" }android.test.* or android.test.mock.* class — all are @Deprecated. New tests use AndroidX Test (AndroidJUnit4, ActivityScenario, ServiceTestRule, ProviderTestRule, Espresso) and org.junit/kotlin.test assertions.testInstrumentationRunner to androidx.test.runner.AndroidJUnitRunner before (or as the first step of) migrating any test class — the legacy InstrumentationTestRunner does not run JUnit4/Espresso.getActivity()/setActivityIntent() with ActivityScenario (launch, onActivity { }), not with ActivityTestRule — ActivityTestRule is itself deprecated.android.test.mock.MockContext/MockResources/MockPackageManager/MockContentResolver subclasses with a real test context where the SUT only reads from it, otherwise a Mockito/MockK mock — never re-derive a new hand-stub from MockContext.extends TestCase, testFoo(), setUp()/tearDown() overrides, junit.framework.Assert) to JUnit4 (@RunWith(AndroidJUnit4), @Test, @Before/@After, org.junit.Assert/kotlin.test) — do not leave a class half-migrated.@deprecated Javadoc's literal target (it often names the obsolete android.support.test.* API); migrate to the current AndroidX target in this skill's table.android.test.*, some on AndroidX) is hard to reason about.androidx.test.ext:truth for the Android subjects) over Hamcrest as the MoreAsserts replacement — better failure messages.git grep -n 'import android.test\.' -- '*.java' '*.kt' is empty (or limited to a tracked, justified holdout list).testInstrumentationRunner is android.test.InstrumentationTestRunner; all are androidx.test.runner.AndroidJUnitRunner.extends ActivityInstrumentationTestCase2 / AndroidTestCase / InstrumentationTestCase / ServiceTestCase / ProviderTestCase2 / junit.framework.TestCase.MoreAsserts. / ViewAsserts. / TouchUtils. references remain.android.test.mock.MockContext / MockResources / MockPackageManager / MockContentResolver remains../gradlew :module:connectedDebugAndroidTest; migrated host tests under ./gradlew :module:testDebugUnitTest.android.test.*.android.test package reference, every class marked deprecated with its replacement pointer.frameworks/base/test-base/src/android/test/AndroidTestCase.java, InstrumentationTestCase.java, UiThreadTest.java, FlakyTest.java (AOSP) — @Deprecated classes whose Javadoc routes to InstrumentationRegistry / androidx.test.annotation.UiThreadTest / androidx.test.filters.FlakyTest.frameworks/base/test-runner/src/android/test/ActivityInstrumentationTestCase2.java, ServiceTestCase.java, ProviderTestCase2.java, InstrumentationTestRunner.java, MoreAsserts.java, ViewAsserts.java, TouchUtils.java (AOSP) — the deprecated runner/base classes; Javadocs name ActivityTestRule/ServiceTestRule/AndroidJUnitRunner/Hamcrest/Espresso as replacements.frameworks/base/test-mock/src/android/test/mock/MockContext.java, MockPackageManager.java, MockContentResolver.java, MockResources.java, MockCursor.java (AOSP) — the stub-context bases; MockPackageManager's Javadoc explicitly says "use a mocking framework like Mockito".../../../instrumentation/runner/running-instrumented-tests-with-androidjunit4/SKILL.md — the AndroidJUnitRunner / AndroidX Test coordinate matrix to land first.../../../instrumentation/scenarios/launching-activities-with-activityscenario/SKILL.md — ActivityScenario / ActivityScenarioRule, the replacement for ActivityInstrumentationTestCase2.../../../instrumentation/scenarios/launching-fragments-with-fragmentscenario/SKILL.md — FragmentScenario for any home-grown fragment-test bases.../../../instrumentation/espresso/writing-espresso-tests/SKILL.md — Espresso ViewMatchers/ViewActions/ViewAssertions, the replacement for ViewAsserts/TouchUtils.../../../jvm-tests/mocking/mocking-with-mockito/SKILL.md — mocking Context/PackageManager/Resources, the replacement for android.test.mock.*.../../../jvm-tests/robolectric/using-robolectric-correctly/SKILL.md — real Android stubs on the JVM, an alternative to a mock context.../../../kotlin/kotlin-test/writing-tests-with-kotlin-test/SKILL.md — kotlin.test assertions (assertEquals, assertContentEquals, assertFailsWith), one valid replacement for MoreAsserts and junit.framework.Assert.../../../fundamentals/strategies/organizing-test-source-sets/SKILL.md — src/test/ vs src/androidTest/, which the migrated classes need to be sorted into.© skydoves, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in platform/legacy/migrating-from-android-test-classes of skydoves/android-testing-skills.
Open the folder on GitHubat commit 8665ed5
Migrating From Android Test Classes next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Migrating From Android Test Classes this skillskydoves/android-testing-skills | 333 | — | ~5.3k | Automated safety check: Pass | Apache-2.0 | |
| Phone HarnessShawnPana/phone-harness | 3.2k | — | ~4.3k | Automated safety check: Pass | MIT | |
| Mobile QAtloncorp/tlon-apps | 107 | — | ~2.4k | Automated safety check: Pass | MIT | |
| Androidyang1ming/android-harness | 176 | — | ~259 | Automated safety check: Pass | MIT | |
| Debug Receiverstimusus/Shuttle2 | 229 | — | ~1.9k | Automated safety check: Pass | Apache-2.0 | |
| Debug Bridgegetknit/knit | 131 | — | ~2.2k | Automated safety check: Pass | GPL-3.0 |
ShawnPana/phone-harness
Control the user's phone — an iPhone through the Mac's iPhone Mirroring window, an Android over adb, or a rented cloud Android: open apps, tap, type, swipe, read the screen.
tloncorp/tlon-apps
Run a mobile QA checklist on a physical Android device over adb for tlon-apps, then triage what fails into fixes.
yang1ming/android-harness
Direct Android device control through ADB. An agent skill from yang1ming/android-harness.
timusus/Shuttle2
Drive the S2 debug build's playback and queue over ADB broadcasts — play the whole library, play/pause, skip, seek, remove a queue item, toggle shuffle/repeat, dump playback state as JSON, reimport…
getknit/knit
Drive and verify Knit on a device or emulator through the headless debug bridge (am broadcast to app.getknit.knit.debug.<ACTION, replies as JSON) — send a message on one phone and confirm it landed…
Moustachauve/WLED-Android
Production-ready scripts for Android app testing, building, and automation.
skydoves/android-testing-skills
A skill your agent uses to verify Compose layout measurements from a UI test using assertWidthIsEqualTo, assertHeightIsEqualTo, assertWidthIsAtLeast, assertHeightIsAtLeast…
skydoves/android-testing-skills
A skill your agent uses to verify a Compose semantics node's properties from a UI test using assertExists, assertDoesNotExist, assertIsDisplayed, assertIsNotDisplayed, assertIsDeactivated…
skydoves/android-testing-skills
A skill your agent uses to render every Jetpack Compose @Preview as a screenshot on a real Android device or emulator and publish a browsable HTML catalog from CI.
skydoves/android-testing-skills
A skill your agent uses to capture visual artefacts from a device for test failures, golden image generation, QA repro, and demo videos.
skydoves/android-testing-skills
A skill your agent uses to pick the correct Compose UI test entry point.
skydoves/android-testing-skills
A skill your agent uses to pick which behaviors to cover in an Android test suite using Google's five-category state vocabulary plus the explicit "what NOT to test" list from…
Works with
Categories
A skill your agent uses to migrate a codebase off the deprecated android.test. Migrating From Android Test Classes is an agent skill from skydoves/android-testing-skills.test.
Migrating From Android Test Classes fits situations like: migrate a codebase off the deprecated android.test; the user sees @Deprecated on android.test; asks how to replace ActivityInstrumentationTestCase2 / InstrumentationTestCase / MoreAsserts / TouchUtils; old Android tests wont run on AndroidJUnitRunner.
Run `npx skills add skydoves/android-testing-skills --skill migrating-from-android-test-classes -a claude-code`. Or copy the skill folder (platform/legacy/migrating-from-android-test-classes in skydoves/android-testing-skills) into .claude/skills/migrating-from-android-test-classes in your project. Claude Code loads it when a task matches its description.
Run `npx skills add skydoves/android-testing-skills --skill migrating-from-android-test-classes -a codex`. Or copy the skill folder (platform/legacy/migrating-from-android-test-classes in skydoves/android-testing-skills) into .agents/skills/migrating-from-android-test-classes in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add skydoves/android-testing-skills --skill migrating-from-android-test-classes -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/migrating-from-android-test-classes, .gemini/skills/migrating-from-android-test-classes, .github/skills/migrating-from-android-test-classes and .opencode/skills/migrating-from-android-test-classes in your project.
Going by SKILL.md and its folder, Migrating From Android Test Classes needs the command-line tools its instructions call (git).
SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Migrating From Android Test Classes is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.3k tokens (SKILL.md is roughly 21k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Migrating From Android Test Classes: Phone Harness (ShawnPana/phone-harness, 3.2k stars), Mobile QA (tloncorp/tlon-apps, 107 stars), Android (yang1ming/android-harness, 176 stars) and Debug Receivers (timusus/Shuttle2, 229 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
skydoves (a GitHub user) maintains it in skydoves/android-testing-skills, which has 333 GitHub stars. The repository holds 50 skills in this directory. The repository was last updated on May 25, 2026.
Source: skydoves/android-testing-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.