用途
本技能用于搭建并正确配置 Android 仪器化测试源集(instrumentation test source set),确保测试能顺利编译并在设备上运行。仪器化测试常常在任何断言执行之前就失败,根本原因通常是运行器栈(runner stack)配置错误。本技能把正确的依赖矩阵、运行器 Gradle 配置以及配套注解和规则固化下来,帮助开发者避开这些陷阱。
适用时机
当出现以下情况时可使用本技能:IDE 将 androidx.test.runner.AndroidJUnit4 标记为 @Deprecated,或测试能编译但产生废弃警告;am instrument 返回 INSTRUMENTATION_FAILED 或 Test runner not found;Gradle 中配置了 Test Orchestrator 但测试仍共享同一个仪器化进程(编排器被静默禁用);用户通过 am instrument 传入 -e size small / -e package 但测试忽略这些参数(RunnerArgs 未接好);测试需要 ACCESS_FINE_LOCATION / RECORD_AUDIO 等权限而用户正手动从 adb 授权;用户想在 API 26 以下跳过某个测试并寻找相应注解。
不适用时机
如果用户是启动 Activity 或驱动生命周期,应参考 ActivityScenario 相关技能;如果是与 View 交互,应参考 Espresso 相关技能;如果是驱动系统 UI 或其他应用,应参考 UiAutomator 相关技能;如果是运行 JVM(Robolectric / 纯 JUnit)测试,应参考 JVM 测试运行器配置技能;如果用户还在决定测什么,应参考测试策略相关技能。
前置条件
需要一个 Android Gradle Plugin 模块(com.android.application 或 com.android.library);磁盘上存在 src/androidTest/ 源集(./gradlew :module:connectedDebugAndroidTest 应能解析);需要模拟器或真机(或 Firebase Test Lab / 托管设备),运行器无法在 JVM 上执行;测试类路径上需要 JUnit 4(junit:junit:4.13.2),JUnit 5 需要 Vintage engine 桥接,不在本技能范围内。
主要能力与工作流
第一步,在 androidTestImplementation 上固定 AndroidX Test 依赖,2026 GA 版本为:androidx.test:core:1.7.0、androidx.test:runner:1.7.0、androidx.test:rules:1.7.0、androidx.test.ext:junit:1.3.0、androidx.test.ext:junit-ktx:1.3.0、androidx.test.ext:truth:1.7.0。其中 androidx.test.ext:junit 才是拥有非废弃 AndroidJUnit4 运行器与 ActivityScenarioRule 的构件;androidx.test:runner 仍带有遗留的(已废弃)AndroidJUnit4,不要从那里导入。
第二步,在模块的 android.defaultConfig 中设置 testInstrumentationRunner,运行器 FQCN 为 androidx.test.runner.AndroidJUnitRunner(注意这是运行器类,与已废弃的 AndroidJUnit4 测试运行器注解不同)。可选通过 testInstrumentationRunnerArguments 传入 -e key value 参数,并设置 testOptions { animationsDisabled = true } 以保证无干扰。
第三步,用 androidx.test.ext.junit.runners.AndroidJUnit4 配合 @RunWith(AndroidJUnit4::class) 注解测试类,这是唯一正确的导入。
第四步,通过 androidx.test.platform.app.InstrumentationRegistry 读取仪器化参数,遗留的 androidx.test.InstrumentationRegistry(没有 platform.app)已废弃。getArguments() 暴露 am instrument -e key value 键值对。
第五步,用 androidx.test.filters 中的 @SmallTest / @MediumTest / @LargeTest 注解测试,配合 -e size small 按速度范围过滤(SmallTest ≤200ms,MediumTest ≤1000ms,LargeTest >1000ms)。同级注解还有 @FlakyTest、@RequiresDevice、@Suppress。@SdkSuppress(minSdkVersion 等) 可限定 API 范围,范围外测试会被跳过(assumption-failure,退出码 -4),而非失败。
第六步,把 Test Orchestrator 加在 androidTestUtil 上(而非 androidTestImplementation),这是运行器栈中最常见的单一配置错误。编排器为每个 @Test 在独立仪器化进程中运行,崩溃只影响该测试,并可在测试间清空包数据。需要同时加 androidx.test:orchestrator 与 androidx.test:services(后者为 clearPackageData 所需),并设置 execution = "ANDROIDX_TEST_ORCHESTRATOR"。androidTestUtil 是特殊 AGP 配置,会在运行前把辅助 APK 安装到设备;若放到 androidTestImplementation 会编译通过但静默无效。
第七步,用 GrantPermissionRule.grant(...) 授予运行时权限,而非 adb shell pm grant,规则来自 androidx.test:rules,在测试类期间授予权限。API 23+ 使用 UiAutomation.grantRuntimePermission,旧设备上权限需已在清单中授予(规则为空操作)。
第八步,禁用动画以保证测试无干扰,animationsDisabled = true 会在测试期间把动画缩放置 0 并在拆卸时恢复原值。
第九步(可选),用 @Rule(order = N) 排序多个规则,序号小的先在外层求值,Hilt 需要 @HiltAndroidRule 处于 order = 0。
第十步,运行:./gradlew :app:connectedDebugAndroidTest,或通过 adb 直接执行 am instrument。必须传 -w(wait),否则即使测试失败 $? 也为 0,退出码无意义。
关键模式
AndroidJUnit4 导入的错与对:错误写法 import androidx.test.runner.AndroidJUnit4(自 runner 1.x 起已废弃),正确写法 import androidx.test.ext.junit.runners.AndroidJUnit4。
InstrumentationRegistry 导入的错与对:错误写法 import androidx.test.InstrumentationRegistry(已废弃,成员均被 @InlineMe 重定向),正确写法结合 androidx.test.platform.app.InstrumentationRegistry 与 ApplicationProvider。
Test Orchestrator 配置的错与对:错误写法把它放到 androidTestImplementation(静默无效,测试仍在单一共享进程),正确写法放到 androidTestUtil 并同时加 services 依赖。
运行时通过 RunnerArgs 过滤测试:可用 -e class 运行单个方法、-e size small 按注解过滤、-e numShards 4 -e shardIndex 0 分片(CI 扇出)。完整支持的 -e 键位于 RunnerArgs.java。
强制规则
必须用 androidx.test.ext.junit.runners.AndroidJUnit4 配合 @RunWith;必须用 androidx.test.platform.app.InstrumentationRegistry;必须把 orchestrator 放到 androidTestUtil;必须设置 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner";必须给 am instrument 传 -w;不得用 Thread.sleep 等待仪器化生命周期,应使用 ActivityScenario.moveToState 或 IdlingResource;不得在测试内用原始 adb shell pm grant,应使用 GrantPermissionRule.grant;不得使用废弃的 @Rule public ActivityTestRule,应使用 @get:Rule val rule = ActivityScenarioRule(...)。推荐给每个仪器化测试类加 @SmallTest / @MediumTest / @LargeTest 注解,便于 CI 分片按大小过滤,并保持 animationsDisabled = true。
验证
./gradlew :<module>:connectedDebugAndroidTest 运行时没有 Test runner not found 或 INSTRUMENTATION_FAILED;没有源文件导入遗留路径 androidx.test.runner.AndroidJUnit4 或 androidx.test.InstrumentationRegistry;grep -r "androidTestImplementation.orchestrator" build.gradle 无结果;am instrument 传 -w 在失败时返回非零退出码;如启用 orchestrator,adb logcat | grep AndroidTestOrchestrator 会显示逐测试进程生成;animationsDisabled = true 已设置;任何运行时权限都有 GrantPermissionRule.grant 规则。
参考与限制
参考资料包括 Android Developers 的 AndroidJUnitRunner 概览、Test Orchestrator、AndroidX Test 发布说明,以及各版本源码行号。本技能不涉及 ActivityScenario、Espresso、UiAutomator、JVM 测试和测试策略选择。具体版本号、退出码、时间阈值等以官方资料为准,本技能未提供官方原文,收费标准等事实暂未提供。