AOSP 测试概述:测试类型与框架速览
做 Android 系统开发,你躲不开的一件事就是测试。说白了,AOSP 测试不是“要不要做”的问题,而是“怎么高效做”的问题。我见过不少团队,代码写得飞起,一跑 CTS 就崩成筛子——嗯,那种痛苦,懂的都懂。
这一章我带你快速捋清楚:AOSP 里到底有哪些测试类型?每个类型的定位是什么?以及背后支撑的那些测试框架,到底各自管什么活儿。别着急,咱们先从最基础的一张图看起。
一、为什么要先聊测试类型?
很多刚接触 AOSP 的人会问:我直接写代码,跑一下 CTS 不就行了?你想想看,如果底层一个单元方法就错了,跑到 CTS 阶段才发现,排查路径有多长。我个人习惯是,先在脑子里画一个“测试金字塔”——
| 测试类型 | 定位 | 典型用例 |
|---|---|---|
| 单元测试 | 验证单个类/方法的行为 | JUnit 4/5 测试一个 Utils 方法 |
| 集成测试 | 验证模块间的交互 | Service 与 ContentProvider 通信 |
| 系统测试 | 验证完整功能 & 系统行为 | Camera 拍照流程、蓝牙配对 |
| 回归测试 | 确保改动不破坏已有功能 | CI 中自动跑的全量测试套件 |
小经验: 我曾经在车载项目里,因为一个 NotificationManager 的单元测试没覆盖,结果 CTS 系统测试跑了三天才暴露——代价太大了。所以现在我坚持:单元测试覆盖率不到 70%,绝不放行集成测试。
二、AOSP 里的关键测试框架
知道了测试类型,还得有趁手的工具。AOSP 社区提供的框架,我挑几个最常用的说一下。
- Robolectric —— 跑在 JVM 上的 Android 单元测试。它模拟了 Android 框架的阴影对象,用起来很爽。我建议你至少把
Activity、Service的单元测试用 Robolectric 覆盖掉。@RunWith(RobolectricTestRunner.class) public class MyActivityTest { @Test public void testButtonClick() { Activity activity = Robolectric.buildActivity(MyActivity.class).create().get(); Button btn = activity.findViewById(R.id.my_button); btn.performClick(); // 验证跳转或状态变化 } } - Instrumentation —— 需要真机或模拟器的测试框架。它跑在设备上,可以操作真实的 UI 和系统服务。比如你测一个“按 Home 键后应用是否切到后台”,就得用 Instrumentation。
public class MyInstrumentationTest extends ActivityInstrumentationTestCase2<MainActivity> { public void testClickAndLaunch() { onView(withId(R.id.btn_next)).perform(click()); intended(hasComponent(NextActivity.class.getName())); } } - TradeFed —— Google 自己的自动化测试框架,用来编排大规模测试任务。CTS、VTS 底层都是它驱动的。你可以理解为一个“测试调度引擎”。
注意: TradeFed 配置复杂,XML 文件动辄几百行。我曾经因为一个
<Option>的 key 写错了,跑了一整夜的全是 SKIP。一定要仔细检查配置模板。 - CTS / VTS —— 兼容性测试套件。CTS 测 Android 应用框架兼容性,VTS 测 HAL 层和内核接口。这些是设备厂商必须过的门槛,也是我们做 Mock 回放的最终验证目标。
三、测试框架怎么选?
你可能会纠结:Robolectric 和 Instrumentation 到底用哪个?其实它们不是二选一的关系。我的经验是:
- 纯逻辑、无 UI 依赖 → Robolectric,又快又稳。
- 需要真实系统服务或 UI → Instrumentation,别偷懒。
- 大规模回归 → TradeFed 调度,搭配 CTS/VTS 跑完整套件。
核心观点: 测试框架只是手段,重要的是你清楚要测什么类型。本教程后面章节的核心就是:如何用 Mock 回放技术,把这些测试跑得更快、更可靠。你已经有了全局视角,接下来我们深入每一层的具体实现。