4. AndroidX Test库概述:核心依赖、测试运行器、Instrumentation与本地测试区别
做系统应用的回归测试,第一关就是搞清楚测试框架怎么选。AndroidX Test 是 Google 官方主推的测试库,说白了就是帮你绕过那些坑爹的系统级限制。
我记得刚开始接触 Android 测试时,还在用 JUnit 3 和旧版的 InstrumentationTestRunner。后来项目迁移到 AndroidX,发现整个测试体系完全变了样。嗯,今天我们就来理一理这些核心组件。
4.1 核心依赖:你最少需要引入哪些库
一个典型的系统应用回归测试,Gradle 里至少要加这几样东西。别贪多,也别漏掉。
// 注意:版本号根据实际项目调整
androidTestImplementation 'androidx.test:core:1.5.0'
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test:rules:1.5.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
每一样都有它的活:
- core —— 提供了 ApplicationProvider、测试生命周期回调。你想想看,没有它,连获取 Context 都得自己写反射。
- runner —— 负责把测试用例跑在设备上。它是整个 Instrumentation 测试的调度中枢。
- rules —— 帮你管理 Activity 启动、权限授予等操作。我习惯用
ActivityScenarioRule替代老旧的ActivityTestRule。 - ext:junit —— 桥接 JUnit4/5,提供
@RunWith(AndroidJUnit4.class)。 - espresso-core —— UI 操作和断言。系统应用里经常要跨进程断言,它比
UiAutomator更轻量。
避坑指南:我曾经过度依赖
androidx.test:monitor,后来发现它底层已经合并到 core 里了。加上反而导致版本冲突。引入前先查一次官网的依赖树。
4.2 测试运行器:AndroidJUnitRunner 到底干了啥
AndroidJUnitRunner 不仅仅是“启动测试”那么简单。它做了三件核心的事:
- 创建 Instrumentation 实例,注入 Application 和 Activity 的上下文。
- 解析
@RunWith注解,找到正确的测试执行逻辑。 - 把每个测试用例放到绑定的进程里运行,并收集结果。
在系统应用的回归场景里,经常需要自定义 Runner。比如我们项目里有一个 SystemAppTestRunner,继承自 AndroidJUnitRunner,额外加了 SELinux 权限配置。你只要在 build.gradle 里指定:
android {
defaultConfig {
testInstrumentationRunner "com.example.SystemAppTestRunner"
}
}
如果你用 AndroidX Test 的默认 Runner,记得在 Manifest 里声明
<instrumentation>。不然测试进程根本进不去。我遇到过好几次这种低级错误。
4.3 Instrumentation 测试 vs 本地测试:到底差在哪
很多新人会混淆这两个概念。我简单列个对比,你就明白了。
| 对比维度 | Instrumentation 测试 | 本地测试 (JVM Test) |
|---|---|---|
| 运行位置 | 真机 / 模拟器 | 开发机 JVM |
| 可访问系统 API | 完全访问(需签名) | 只能 mock |
| 执行速度 | 慢(需安装 APK) | 快(毫秒级) |
| 需要 Android 上下文 | 有 | 无 |
| 适合场景 | 系统 UI、跨进程、真实 HAL | 纯逻辑、数据层、Unit 测试 |
为什么系统应用回归更依赖 Instrumentation 测试?
- 因为很多系统 API 是隐藏的,本地测试根本调不动。
- 因为测试需要和系统服务交互,比如
ActivityManager、WifiManager,只有真机上才真实。 - 因为回归要求高可信度,mock 出来的东西不可靠。
但也不要全盘抛弃本地测试。我自己的习惯是:逻辑层用本地测试快速验证,系统交互层用 Instrumentation 测试做回归。两种并行,效率最高。
注意:Instrumentation 测试会真正安装 APK 并运行,因此测试 APK 和被测 APK 必须共享同一个进程或签名。系统应用通常 platform 签名,测试包也必须同样签名。否则会报 SecurityException。踩过这个坑的人应该不少。
4.4 一张图看懂 AndroidX Test 库结构
下面这个图,把核心组件、运行流程和两种测试类别串在一起。你看一遍就能回忆起整个体系的脉络。
4.5 归纳总结:什么时候该用哪个
说一千道一万,你只需要记住两条原则:
- 如果你要测试的代码不依赖 Android 框架(比如数据解析、工具类),优先写本地测试。运行快、不依赖设备。
- 如果你是做系统应用的回归,涉及 Activity 跳转、系统服务调用、权限弹窗、跨进程通信,必须上 Instrumentation 测试。别省这一步,否则线上出问题你根本猜不到原因。
我个人的建议是:在一个系统项目里,用 70% Instrumentation 测试 + 30% 本地测试 的比例来分配。本地测试跑在 CI 的快速检查阶段,Instrumentation 测试跑在夜间回归。这样既保速度又保质量。