把测试通过变成验收证据
“测试通过了”不是证据。
它最多是证据的标题。
真正有用的测试证据,要能回答:
- 测了什么行为?
- 用了什么输入?
- 控制了哪些依赖?
- 覆盖了哪些路径?
- 命令是什么?
- 输出是什么?
- 哪些风险还没测?
- 这个结果能不能支持验收?
如果这些问题答不上来,一句“测试通过”并不能让系统更安全。
一、测试不是越多越好,而是越贴边越好
很多项目会陷入一种焦虑:测试覆盖率越高越安全。
覆盖率有价值,但覆盖率不是安全本身。你可以写很多不痛不痒的测试,也可以漏掉真正会让线上出事的路径。
测试要贴着问题定义、设计边界和失败模式。
一个改动如果是修复状态写回失败,最重要的测试不是“导出成功”。最重要的是:
- 上传成功但状态写回失败时,任务是否保留可恢复状态。
- 重试是否幂等。
- 重复触发是否不会生成两个导出文件。
- 状态为空或历史状态不认识时是否降级。
- 依赖失败时是否留下可观测错误。
这叫贴边。
二、把测试结果写成台账
我现在更喜欢用测试证据台账,而不是只写一段测试总结。
格式可以很简单:
1 | | 链路 | Path | 输入 / Fixture | 命令 | 结果 | 证据 | 风险 | |
这张表的价值不是好看,而是让验收者能迅速判断:证据够不够支持发布。
它把“测试通过”拆成了具体问题:
- 通过的是哪条链路?
- 属于 happy、nil、empty、error 哪个路径?
- 输入是什么?
- 用什么命令验证?
- 证据在哪里?
- 风险是否仍然存在?
三、没有测到的也要写
成熟的测试证据不是假装覆盖一切,而是诚实写出没覆盖什么。
例如:
1 | Not Covered: |
这比一句“测试通过”有价值得多。
未覆盖风险不是失败。隐藏未覆盖风险才是失败。
工程里真正危险的不是“我们知道这个风险还没测”,而是“大家以为它测过了”。
四、区分 Test Plan 和 Test Blueprint
一个常见混乱,是把“未来想测什么”和“现在已经测了什么”混在一起。
所以要区分 Test Blueprint 和 Test Plan。
Test Blueprint 是目标态自动化蓝图。它可以写:
- 将来应该补哪些层级的测试。
- 哪些路径适合单元测试。
- 哪些路径适合集成测试。
- 哪些路径需要 UI 自动化。
- 哪些路径只能人工验收。
Test Plan 是当前可执行验证。它必须写:
- 本次实际跑哪些命令。
- 预期结果是什么。
- 实际结果是什么。
- 证据在哪里。
- 哪些没测。
Blueprint 可以理想,Plan 必须诚实。
如果把 Blueprint 当成 Plan,你会得到一种虚假的安全感:文档里看起来什么都覆盖了,但实际上当前没有一条证据。
五、Fixture、Mock、Stub、Fake 的边界
测试证据链离不开依赖控制。
Fixture 是测试输入和环境样本。
坏 fixture 叫:
1 | user1 |
好 fixture 叫:
1 | loggedInUser |
命名本身就是测试文档。
Stub 提供固定返回,适合控制简单依赖,比如配置读取、时间、当前用户。
Mock 关注交互是否发生,适合验证“是否调用了某个依赖”“调用参数是什么”“调用次数是否正确”。Mock 用多了会绑死实现细节,所以要谨慎。
Fake 是可工作的轻量实现,比如内存数据库、内存队列、临时文件系统、假的上传服务。Fake 通常比 mock 更适合测试状态流,因为它允许行为自然发生,而不是只验证调用。
选择原则:
- 想控制输入,用 fixture。
- 想固定返回,用 stub。
- 想验证交互,用 mock。
- 想模拟真实行为,用 fake。
六、验收不是跑完测试
测试通过只是验收材料之一。
验收要回答更大的问题:
- 本次目标是否完成?
- In Scope 是否全部覆盖?
- Out of Scope 是否没有被带入?
- 关键路径是否验证?
- 四路径是否覆盖?
- 哪些风险没有覆盖?
- 是否需要发布?
- 如果发布,如何观察?
- 如果失败,如何回滚?
也就是说,验收是把需求、设计、测试、review 和发布风险收束到一个判断。
验收结论最好不要只有“通过 / 不通过”。
可以分成三类:
- Accepted for current scope。
- Accepted with residual risks。
- Not accepted; requires fix。
第二类很重要。很多真实任务不是零风险,而是在明确风险后接受。
例如:
1 | Accepted with residual risks. |
这比“通过”更诚实,也更适合复盘。
七、发布前还要问观察和回滚
如果一个改动会影响用户、数据、接口、配置、队列、存储、权限、支付、同步或后台任务,就不能只靠测试结束。
发布前还要问:
- 发布后观察多久?
- 看哪些指标?
- 看哪些日志?
- 哪些用户路径要冒烟?
- 什么条件触发回滚?
- 回滚命令是什么?
- 回滚会不会破坏新数据?
没有观察窗口的发布,本质上是在靠感觉。
一个更好的发布观察写法是:
1 | Observe Window: 发布后 30 分钟 |
这才是把发布拉进控制面。
八、完成必须带证据
任务结束时,最好的收尾不是“已完成”,而是:
1 | Changed: |
这几项看起来普通,但它们能显著减少后续扯皮和返工。
“测试通过”是一句话。
“验收证据”是一组可复查事实。
AI 时代代码会来得越来越快。越是这样,我们越需要把测试从一个动作,升级成一条证据链。