背景
在软件的开发流程里,持续集成是推动开发工作的动力,是软件质量的关键保障。通常持续集成由代码ci规则、UT、回归、failover、压测、性能测试、运维测试、灰度测试等流程构成。那么如何衡量持续集成对于软件质量的作用呢?能不能量化评估?评估方案应该由哪些部分组成?通过测试覆盖率来衡量持续集成的效果是其中的一个角度,测试覆盖率又可以细分为代码覆盖率和日志覆盖率,代码覆盖率包括函数覆盖率、行覆盖率、分支覆盖率等等,日志覆盖率包括常规日志覆盖率、异常日志覆盖率、增量日志覆盖率。本文将详细介绍这两类覆盖率的评估方法与开源工具。
代码覆盖率
以c/c++语言为例(作者只玩过这种语言的)
开源社区比较有代表性的就是gcov工具
用法:
- 用GCC编译的时候加上-fprofile-arcs -ftest-coverage选项,链接的时候也加上
- 执行UT
- 重置计数器,lcov –directory . –zerocounters
- 收集当前代码覆盖状态到一个文件,lcov –directory . –capture –output-file app.info
- 获取HTML输出,genhtml -o results app.info
默认支持采集函数覆盖率和行覆盖率
分支覆盖率需要在第4步加入–rc lcov_branch_coverage=1参数
增量覆盖率需要用到addlcov工具,addlcov可以根据对比两个目录下文件的差异列表,对指定代码形成覆盖率数据
- 使用diff命令生成文件差异列表
diff -r -N -x “.git” -x “*.gcov” -u <old_src_path> <new_src_path> > diff.txt
其中<old_src_path>是v1版本代码路径、<new_src_path>是v2版本代码路径,生成的diff.txt中包含的就是v2相比v1的增量代码
- 使用addlcov生成增量代码覆盖率文件
addlcov –diff <full_cov_file> diff.txt -o <add_cov_file> –strip–path <new_src_path>
其中<full_cov_file>为之前统计的v2版本上的全量覆盖率;<add_cov_file>为输出的增量覆盖率info文件;
这里的
- 使用genhtml生成html格式的覆盖率报告
genhtml -o <report_dir> <add_cov_file>
其中<report_dir>是想要生成的报告路径名称,<add_cov_file>是通过上一步生成的覆盖率文件
商业软件比较有代表性的就是BullseyeCoverage工具, 使用方法类似,具体就不介绍了
日志覆盖率
原理比较简单:
- 扫描源代码中所有日志行,一般日志通常会LOG()这种形式构成,可以指定日志关键字,扫出日志记录的结构为(日志文件名称,代码行数,详细内容)。其中比较复杂一点的就是多行日志的处理,可以以LOG(为起始关键字,);为终止关键字,得到多行日志的记录。
- 扫描所有日志文件,按照固定的打日志格式,提取出每条日志对应的文件名和行号,然后再做一次去重处理
- 根据日志文件提取出的信息,按照文件名 + 行号计算匹配率,更细致的,可以按照日志级别,分为常规日志覆盖率和异常日志覆盖率
- 通过记录历史的代码文件覆盖率信息,与当前文件的覆盖率信息做对比,可以得到增量覆盖率信息。
这种处理方式,会存在几个比较难解的问题:
- 对于宏日志的覆盖率统计是没有效果的。
- 通常不太可能实现只统计一个版本的覆盖率信息,而是需要看一个大版本下所有小版本合并后的总覆盖率信息,由于代码行号漂移,这里会存在重复统计的问题。
- 这种统计行为,只能寄希望于开发的日志打的合理,且全面,才有可能得到高日志覆盖率 可能正比于 高质量,而且没有办法清楚的表达80% 和 90%覆盖的质量差距在哪里?100%覆盖是否代表没问题?