一句话定义:代码覆盖率(Code Coverage)衡量的是测试运行时,你的源码中有多少比例被“执行过”。注意关键词是执行,不是验证。
它是怎么算出来的
覆盖率工具会在代码里做插桩(instrumentation)——可以想象成在每一行代码门口装一个红外感应器。你跑一遍测试套件,感应器记录下哪些门被推开过,最后生成一份报告:100 行代码里 82 行有人进去过,覆盖率就是 82%。
打个更贴切的比方:消防检查。检查员拿着楼层平面图,看每个房间有没有人进去过、有没有在签到表上打勾。但“进去过”和“检查了灭火器压力是否正常”是两件事。覆盖率统计的是前者。
常见的有几个层级:语句覆盖(Line/Statement Coverage)看行有没有被执行;分支覆盖(Branch Coverage)看每个 if/else、循环的每个出口是不是都走过;路径覆盖(Path Coverage)看多条分支的组合路径。一段 if (x > 0) 的代码,测试只喂了正数,语句覆盖可能接近满分,分支覆盖却只有一半。
和相邻概念的区别
很多人把“覆盖率高”当成“测试好”,这两者之间隔着一条鸿沟。最大的漏洞是断言(assertion):测试函数被调用、代码被执行,但没人检查返回值对不对,覆盖率照样能刷到 100%。更狠的检验手段是变异测试(Mutation Testing)——故意往代码里注入小错误(把 > 改成 >=、把返回值改掉),看测试能不能抓出来。抓不住,说明测试只是“路过”,没有“把关”。
| 指标 | 衡量什么 | 局限 |
|---|---|---|
| 语句覆盖 | 多少行代码被执行过 | 不检查执行结果,跑了但没验证也能满分 |
| 分支覆盖 | 每个判断的各个出口是否都走过 | 仍只统计路径触及,不验证正确性 |
| 变异测试 | 注入人为 bug 后测试能否发现 | 计算成本高,通常抽样或对关键模块使用 |
为什么 AI 写的代码尤其容易制造覆盖率幻觉
AI 很擅长“照着实现反推测试”:函数里有什么分支,它就写一个刚好走那条分支的用例。结果是覆盖率漂亮,但测试和实现是同一套思路的复读——实现错了,测试跟着一起错。再加上 AI 常生成一批防御性分支和边界判断,这些行被“执行”过,逻辑却从未被真正质疑。覆盖率因此从“质量指标”退化成“装饰指标”。
实际怎么用
把覆盖率当雷达,别当奖杯。它是有用的反向指标:覆盖率低,说明一定有没测到的地方;覆盖率高,什么也证明不了。可以重点关注两块:新增代码的覆盖率(diff coverage),以及分支覆盖而非语句覆盖;再抽时间人工看一眼 AI 生成的测试里有没有实质断言、有没有断言“等于实现里那个常量”这类同义反复。工具的具体配置和阈值以各项目官方页面为准。
对非技术同事的一句话版本:体检项目全做完了,不等于体检结果都正常。覆盖率只回答“做没做”,不回答“对不对”。
