代码覆盖率
全量、增量与累计代码覆盖率的实践方法
代码覆盖率(Code Coverage)是软件测试中的一种度量方式,用于描述程序中源代码被测试执行到的比例和程度,所得比例即为代码覆盖率。
代码覆盖率指标通常包含下面几类:
- 函数/方法覆盖率:函数/方法中有多少被调用到
- 分支覆盖率:有多少控制结构的分支(例如
if语句)被执行 - 条件覆盖率:有多少布尔子表达式被测试为真值和假值
- 行覆盖率:有多少行源代码被执行过
代码覆盖率的意义
- 测试视角:分析未覆盖部分的代码,从而反推前期测试设计是否充分。没有覆盖到的代码是否是测试设计的盲点?为什么没有考虑到?是需求/设计不够清晰,还是测试设计的理解有误?抑或是工程方法应用后造成的策略性放弃?这些反思方便之后进行测试用例补充。
- 开发视角:检测出程序中的废代码,可以逆向反推代码设计中的思维混乱点,提醒设计/开发人员理清代码逻辑关系,提升代码质量。
- 其他视角:代码覆盖率高不能说明代码质量高,但反过来看,代码覆盖率低,代码质量也不会高到哪里去。它可以作为测试/开发自我审视的重要工具之一。
以上是代码覆盖率正面的意义,但要注意一点:从质量角度来说,肯定希望用例能够对代码全部进行覆盖,但从实际出发,进行全覆盖并不现实。把测试覆盖率作为质量目标没有任何意义,我们应该把它当作一种发现未被测试覆盖代码的手段。从现有的覆盖率检测工具来看,即使覆盖率达到 100%,也不能保证用户场景完全被覆盖到或不会出现漏测——从原理上讲,代码覆盖率只能表示开发写的代码都执行了,但并不表示代码没有逻辑问题,例如漏写异常处理、没有完全覆盖用户场景等。
lcov(.info) 格式解析
如何做覆盖率
1. 全量覆盖率
适用场景:
- 初次测试:开始进行测试时,全量代码覆盖率非常有用。它可以确保测试用例覆盖整个代码库,从而验证代码在各种场景下的正确性和稳定性。
- 重构和优化:在进行重构或性能优化时,全量代码覆盖率可以帮助发现可能引入的新问题,并确保代码的质量和性能未受到不良影响。
- 稳定版本验证:在发布稳定版本之前,全量代码覆盖率可用于验证所有已经修改或新增功能的测试覆盖程度,以确保发布的版本是经过全面测试的。
- 其他需要全量回归的场景,例如:机房迁移、新环境部署等。
2. 增量覆盖率
JaCoCo 本身是不支持增量代码覆盖率的,但可以通过二次开发或者使用其他的开源工具实现增量覆盖率报告生成。
适用场景:
- 快速迭代测试:在项目快速迭代的情况下,仅针对新增或修改的代码进行增量代码覆盖率分析,能够快速确定这些变动的测试覆盖程度,以便加快迭代速度。
- 高频更新验证:对于经常更新的代码库,每次都进行全量代码覆盖率分析可能会产生高昂的计算和执行成本。使用增量代码覆盖率可以更快地了解测试覆盖的变化情况,以便快速验证新增功能的正确性和稳定性。
- 增量测试补充:当时间有限而需求变动时,增量代码覆盖率可用于快速确定需求变动对现有测试覆盖的影响,并有针对性地补充和调整测试用例,以覆盖新增或修改的代码。
为了保证代码质量,一般会要求提交的源码要有测试用例覆盖,并对测试覆盖率有一定的要求。实践中不仅会考核存量代码覆盖率(总体覆盖率),还会考核增量代码的覆盖率。或者说增量覆盖率更有实际意义:测试用例要随源码一并提交,实时保证源码的质量,而不是代码先行、测试用例后补——那样有些应付的意味。
对于存量代码覆盖率,主流的测试工具(框架)都是默认支持的,配置 reporter 相关参数,执行完测试用例就会生成测试报告。
对于增量测试覆盖率,主流的测试工具一般没有原生支持。作者认为,计算增量代码貌似不是测试工具该干的事,所以主流测试工具并没有提供这一功能。
那么如何计算增量覆盖率呢?计算增量测试覆盖率,总共需要 3 步:
- 计算出增量代码的所有行号
- 计算出测试未覆盖的代码的所有行号
- 对比计算增量代码被测试覆盖的比例,得出增量覆盖率
参考
3. 累计代码覆盖率
累计代码覆盖率首先得解决不同版本代码合并的问题。
跨版本合并
跨版本代码合并的流程大致如下:
# diff 文件中的路径名必须是绝对路径
diff -u $(PWD)/hello_old.c $(PWD)/hello_new.c > difffile
# 不加 --convert-filenames 的话,RUN1 的数据
# 仍会关联到 hello_old.c
lcov --diff RUN1.INFO difffile --convert-filenames -o RUN1_CONVERTED.INFO
# 合并两次运行的数据
lcov -a RUN1_CONVERTED.INFO -a RUN2.INFO -o RUN_ALL.INFO三者区别
在 perplexity.ai 中搜索「全量代码覆盖率、增量代码覆盖率、累计代码覆盖率」会给出如下回答(以下内容由 AI 生成,仅供参考):
全量代码覆盖率、增量代码覆盖率和累计代码覆盖率是衡量软件测试质量的重要指标,下面对这三种覆盖率进行详细解释。
全量代码覆盖率:指在整个代码库中,经过测试用例执行后实际被执行的代码行数与总代码行数的比例,通常用于评估整个项目或模块的测试充分性。一般要求达到 70% 至 80% 之间,以确保大部分代码路径都经过测试。
增量代码覆盖率:指在特定版本或迭代中新增或修改的代码行被测试用例覆盖的比例,主要用于评估每次迭代对新代码的测试情况。通常要求更高,服务端项目可能要求 80%-90%,而移动端和前端项目则要求 70%-80%,这种高标准确保了新功能或修复的可靠性。
累计代码覆盖率:指在整个开发周期内,所有版本中被测试用例执行过的代码行数与总代码行数的比例,反映了随着时间推移项目整体的测试情况。通常会随着项目的发展而提高,开发团队会设定阶段性目标,例如核心业务代码分支覆盖率达到 50% 或更高。
总结:这三种覆盖率各有侧重——全量代码覆盖率关注整体质量,增量代码覆盖率强调新功能的可靠性,累计代码覆盖率则反映长期的测试成果。通过合理设置这些指标,可以有效提升软件质量并降低潜在风险。