用途
Choosing What to Test 是一个 Android 测试技能,用来帮助开发者或代理(agent)判断某个 Android 模块、类或函数“应该覆盖哪些行为”。它解决的问题是:Android 测试套件常常对业务逻辑覆盖不足,却对框架胶水代码覆盖过多。该技能基于 Google 官方关于“what to test”的页面,把测试价值按代码所触及的状态类型进行归类,并显式列出应避免的测试类别和边界情况清单,从而能给出具体建议,而不是笼统地说“重要内容都要测”。
何时使用
- 用户问“这个模块应该为哪些内容写测试”或“X 需要测试吗”。
- 用户问是否要对 Activity、Fragment 或 Service 做单元测试(答案通常是“不”,见“不应测试的内容”)。
- 用户在评审 PR,但测试缺口不明确。
- 用户问“这个函数我漏了哪些边界情况”。
- 用户问测试投入应落在 ViewModel、Repository 还是 Composable 之间。
何时不使用
- 用户已知道要测什么,正在选择测试范围(small/medium/big)——应使用 understanding-the-testing-pyramid 技能。
- 用户正在选择 fakes / mocks / stubs——应使用 picking-test-doubles 技能。
- 用户正在配置源码集(src/test/ 与 src/androidTest/)——应使用 organizing-test-source-sets 技能。
前置条件
- 一个至少包含一个 ViewModel、repository 或 screen 的模块。
- 熟悉 Android 架构分层(UI / Domain / Data),以便把“data layer”映射到真实路径。
- 来自 understanding-the-testing-pyramid 技能的三层金字塔框架。
需要覆盖的五类状态
- 屏幕上的状态:用户当前能观察到的内容,例如按钮文字、列表数量、启用/禁用状态、复选框切换。通过 UI 测试验证,例如 Compose 使用 onNodeWithTag(...).assertIsDisplayed() / assertTextEquals(...) / assertIsEnabled();View 使用 onView(...).check(matches(isDisplayed()))。
- 内存中的状态:ViewModel 与 presenter 的状态,例如 ViewModel.uiState、内存缓存、当前选中项。通过小型单元测试验证,使用 fake repository 启动 ViewModel,驱动事件并断言暴露的 StateFlow / LiveData。
- 持久化状态:数据库、DataStore、SharedPreferences、文件等能跨进程死亡存活的状态。分为两类:Repository 单元测试(fake 存储源,验证缓存、映射、错误处理)与存储集成测试(使用真实的 Room / DataStore / SharedPreferences 实现,属于小型 instrumented 测试)。
- 其它状态:系统栏、系统服务、闹钟、广播,例如 window-insets 状态、深色模式标志、闹钟调度、后台任务状态。在有 shadow 时可用 Robolectric(medium-local),需要真实系统时用 instrumented 测试。
- 错误与边界情况:包括负数、零、边界条件下的数学运算;所有可能的网络连接错误;损坏数据(如格式错误的 JSON);保存文件时的存储已满;进程中途对象重建(如设备旋转时的 Activity)。这是测试预算中价值最高的一栏。