覆盖率是手段,不是目的
很多团队把覆盖率当成 KPI:覆盖率必须到八十、九十。但覆盖率数字高,并不代表测试真的有用——它只说明这些代码被「执行到过」一次。
覆盖率真正该回答的问题是:这些测试能不能在代码改错时真的把错抓住。抓不住错的高覆盖率,只是一张自我安慰的成绩单。
一个覆盖率九十却抓不住任何错的测试套件,比覆盖率三十但每次都能报警的套件更危险——因为它给了人虚假的安全感。
本文核心知识点
- 覆盖率只是执行到过,不等于验证了。
- 断言没有断言的测试抓不住错。
- 门槛覆盖率门槛要现实可达。
- 不稳定测试时过时不过的测试最伤信任。
- 治理找出病根,别靠重跑碰运气。
覆盖率到底在测什么
覆盖率有不同层次,从粗到细看,意义差别很大。最常用的是行覆盖和分支覆盖,后者要求每个分支的真假两条路都走到。
| 层次 | 看什么 |
|---|---|
| 行覆盖 | 这行代码被执行到过吗 |
| 分支覆盖 | 每个条件的真假两路都走过吗 |
| 关键路径 | 真正重要的业务流程被验证了吗 |
与其追一个虚高的总行覆盖,不如盯着关键路径有没有被真正验证。
别被假绿骗了
有一种测试,跑是跑了,覆盖率也上去了,但它根本没有断言——也就是没有检查任何结果。这种测试永远是绿的,看起来很美,实际上啥也没守住。
# 坏例子:覆盖到了,但啥也没验
调用一下函数,不检查返回值
不抛异常就算过
# 好测试必须有断言:
result = 计算(输入)
assert result 等于预期
# 没有断言的测试,只是在给覆盖率凑数。
评审时多问一句:这个测试到底在验证什么?答不上来,它就是个凑数的。
覆盖率门槛:定多高合适
覆盖率门槛是把双刃剑。定得太低形同虚设,定得太高团队就会去写凑数测试来达标。门槛应该现实可达,并且重点放在关键模块。
| 做法 | 说明 |
|---|---|
| 核心模块高门槛 | 钱、订单这些关键路径严一点 |
| 整体门槛渐进 | 随新代码逐步提高,不一步到位 |
| 新增代码必测 | 新改动的覆盖率要过关 |
把门槛用在刀刃上,比全公司一刀切一个数字要健康得多。
不稳定测试:自己会挂的测试
最伤团队信任的,是那种时过时不过的「不稳定测试」:代码没改,这次跑挂了,重跑又好了。大家见多了,慢慢就对红灯麻木了。
# 不稳定测试的常见病根
- 依赖了真实时间,测试结果随时间变
- 依赖了执行顺序或外部共享状态
- 有没等异步完成就断言
- 依赖网络或环境,时好时坏
# 重跑过了不叫修复,叫运气好。
一个经常自己挂的测试,比没有测试更糟——它教会大家忽略红灯。
治理不稳定测试:找出病根
治理不稳定测试,不能靠「挂了就重跑」,而要把它抓出来、隔离、修好。
- 给频繁挂的测试打标记,单独统计和重跑。
- 复现并找出病根:时间、顺序、异步、环境。
- 把依赖隔离开,让测试在任何环境任何顺序下都稳定。
把不稳定测试一个个揪出来治好,测试套件的可信度才能真正回来。
让测试真的可信
覆盖率与不稳定测试治理的最终目的,是让测试套件真的能在代码改错时报警,团队才敢放心地频繁改代码。
- 覆盖率看关键路径,不追虚高数字。
- 每个测试都有断言,真的在验证行为。
- 不稳定测试被持续治理,红灯值得相信。
当测试值得信任,它就从一项负担,变成团队敢于频繁改进的底气。