Compose快照回归常见错误与解决方案教程 - 第1节
一、快照回归测试到底是什么
做 Android 开发的,特别是玩 Compose 的,一定遇到过这种情况:
某天你改了一行看似无关的代码,结果 UI 跑偏了。按钮歪了,间距没了,颜色不对。
你把它改回来?但你已经忘了原来长啥样了。
嗯,我就是被这个问题折磨过好几次,才下定决心把快照回归测试请进项目里的。
啥是快照测试?
说白了,就是给你的 UI “拍张照”。
你写了一个 Composable 组件,测试框架会把它渲染出来,截一张图保存下来。
下次再跑测试的时候,它又会截一张新图。
新旧两张图一对比,不一样的地方就会标红。
这个截图,就叫快照。
这个比对过程,就叫回归检验。
你可以把它理解成“版本控制给 UI 用”。
代码有 Git 管理,UI 凭什么没有?
为什么需要回归测试?
人不是机器。再厉害的工程师,改 UI 也会有疏漏。
- 改了一个颜色值,影响了 10 个页面——你只测了首页,别的崩了。
- 重构了布局组件——你觉得没变,但有些边距偷偷变了。
- 第三方库升级了——默认样式变了,你根本没注意。
快照回归测试可以在你提交代码前,像哨兵一样提醒你:
“诶,这个界面和上次不一样了,你确定要改吗?”
Compose 里快照测试的特殊之处
你可能做过传统的 View 系统截图测试。
但 Compose 的玩法不一样。
| 维度 | 传统 View 截图 | Compose 快照 |
|---|---|---|
| 渲染方式 | 依赖 Activity / Fragment | 纯组合函数,无需 Activity |
| 环境依赖 | 需要真机或模拟器 | 可运行在 JVM(使用 Robolectric) |
| 截图内容 | 全屏或指定 View | 只截取 Composable 边界内 |
| 对比精度 | 像素级,易受设备影响 | 可配置阈值,更灵活 |
| 维护成本 | 高(每次设备更换都要重新截图) | 低(记住基线,只在业务变化时更新) |
Compose 的快照测试可以在纯 JVM 环境下跑。
不需要开模拟器。
不需要等构建。
速度快到可怕。
我记得第一次把 Compose 快照接入流水线的时候,全组都震惊了。
以前跑完整 UI 测试得十几分钟,现在几十秒搞定。
一个简洁的流程示意图
下面这张图,帮你把整件事串起来:
我当年在项目里第一次跑通整条链路的时候,感觉像是请了一个永远不睡觉的 QA。
什么时候该用快照回归?
不是所有场景都适合。我遇到过有人把网络请求的结果也放进了快照里,那是胡闹。
- 静态 UI 组件:按钮、卡片、列表项、弹窗样式——强烈推荐
- 状态驱动的 UI:loading / error / empty / content 四种状态——非常适合
- 主题切换组件:亮色/暗色模式——一个快照测两个风格
- 动态内容区域:不推荐,建议用传统单元测试替代
每次截图都不一样,测试永远过不了。白白浪费两小时。
如何开始写第一个快照测试?
在 Compose 里,一个简单的快照测试长这样:
@Test
fun myButton_snapshot() {
composeTestRule.setContent {
MyButton(text = "点击我")
}
// 与基线对比
composeTestRule.onRoot().captureToImage()
}
但这只是表面。真正的核心在于基线管理和差异分析。
我会在后面的章节里,一步步带着你搭一个完整的快照回归测试框架。
从选择工具库,到配置 CI 流水线,再到处理那些“老改不对”的棘手情况。
千万别跳过。这些内容都是我亲手淌过一遍的经验。
好了,第一章就说到这里。
你至少明白了什么是快照测试,为什么它重要,以及它在整个 Compose 项目里的位置。
下一件事情?
嗯,回去看看你项目里的 UI 改动频率,找一两个组件练练手。