建议先阅读iOS单元测试数据统计 和 iOS代码覆盖率统计。
本文涉及的所有脚本均托管在GitHub项目 UnitTestParser 中。
Demo工程:UnitTestDemo
简介
增量代码覆盖率
指的就是新增代码的代码覆盖率,也就是新增代码中有多少代码被单元测试覆盖了。我们可以通过如下公式计算增量代码覆盖率
1 | deltaCov = coveredDeltaLineCount / deltaLineCount |
其中,deltaLineCount 指的是新增代码中的有效代码行数,coveredDeltaLineCount 指的是新增代码的有效代码行中,被单元测试覆盖的行数。用后者除以前者,就得到了本次新增代码的覆盖率,也就是增量代码覆盖率。
使用场景
增量代码覆盖率可以保证增量代码的单元测试水平,从而保证整体单元测试水平不断提升。一般情况下,我们会在如下几个场景统计增量代码覆盖率:
- 有新的 PR(Pull Request)或 MR(Merge Request)时,检测本次PR/MR的增量代码覆盖率,决定是否合入。
- 检测不同版本之间的增量代码覆盖率,评估每个版本的增量代码单元测试水平。
- 定时检测每天的增量代码覆盖率,保证代码单元测试水平不断提升。
增量代码覆盖率可以很好地体现新增代码的单元测试水平,有了增量代码覆盖率数据支撑之后,我们才能站在更高维度上把控项目代码的整体单元测试水平,提升代码覆盖率。
增量覆盖率计算
我们再回到增量代码覆盖率的计算公式:
1 | deltaCov = coveredDeltaLineCount / deltaLineCount |
我们已经知道,deltaLineCount 指的是新增代码中的有效代码行数,coveredDeltaLineCount 指的是新增代码的有效代码行中,被单元测试覆盖的行数。
所以如果想计算增量代码覆盖率,我们需要分三步走:
- 找到新增了哪些文件的那些代码行
- 获取单个文件的代码覆盖率报告,确定每一行的覆盖情况
- 确定新增的代码行是否被单元测试覆盖
下面就按这3步来各个击破。
1. 新增代码统计
怎么去找到本次提交/MR修改了哪些文件的那些代码行呢?
如果大家看过了获取git增量代码数据这篇文章的话,相信这不会是个问题。通过解析git diff
的数据,我们就能够获取到
增量代码文件以及对应的代码行。
2. 单个文件覆盖率报告
通过新增代码统计获取到所有新增的文件之后,我们需要对每个文件进行单独的处理,确定这个文件的每一行是否被覆盖。因此,我们必须能够获取单个文件的代码覆盖率报告。
以UnitTestDemo项目为例,使用如下命令就可以从 .xcresult 文件中获取到单个文件的代码覆盖率情况,其中包括了每一个代码行被单元测试执行的次数。
1 | # /path/to/file 为执行单元测试时文件的绝对地址 |
上面命令的输出结果如下:
1 | 1: * |
如果输出报错,先通过
xcrun xccov view --archive --file-list test.xcresult
命令查看填写的文件路径是否正确。
左侧的索引就是文件的代码行索引,右侧的数字表示的是该行在单元测试中被执行的次数,其中 *
表示该行不是可执行代码行,比如空白行等,在进行覆盖率计算时,这些行不会被当成有效代码行,也就不会被统计进去。
相信看到这里大家就知道增量覆盖率计算公式中的有效代码行是什么意思了。
3. 确定新增代码行是否被覆盖
通过上面的两步,我们就拿到了本次修改的文件及代码行,及每一个代码行是否被单元测试覆盖。接下来我们只需要针对每个文件逐行去解析即可。统计规则如下:
- 新增可执行代码行:行索引后面不为
*
- 被覆盖的新增可执行代码行:行索引后面不为
*
,且数字大于0
UnitTestParser项目提供了 deltaCov.rb 脚本来实现增量代码覆盖率的解析和输出。
例如执行:
1 | ╰─± ruby deltaCov.rb --xcresult-path=path/to/xcresult_file --proj-dir=./ --diff-file=path/to/diff_file --output-file=deltaCov.txt |
则会输出:
1 | 新增代码覆盖率:1.0 |
如果输出报错,先通过
xcrun xccov view --archive --file-list test.xcresult
命令查看填写的文件路径是否正确。
同时这些数据也会被写入到 deltaCov.txt 文件中,便于其他工具读取。
1 | ╰─± cat deltaCov.txt |
总结
UnitTestParser项目提供的脚本可以快速准确地解析出增量代码行数和增量代码覆盖行数,进而计算出增量代码覆盖率。