代码覆盖率,是一种依靠计算测试过程中被执行源码占全部代码行的比例,进而度量测试用例对程序覆盖的情况,从而查漏补缺,完善软件质量的方法。
那么做代码覆盖率统计的意义是什么呢?通过研究代码覆盖率报告,一方面我们可以直观的发现没有被测试用例测试过的代码,另一方面也能发现开发人员在新版本中新增/修改了哪些代码,从而及时的更新测试用例来增加覆盖率:保证程序功能的覆盖度。
在具体的实施过程中,中通是如何将代码覆盖率运用到实践中的呢?本文将对此展开详细讨论
在开始介绍具体的实现方案之前,我们先了解一下目前使用的代码覆盖率工具 Jacoco。作为一款开源的覆盖率工具,它能够应用在 java 服务端项目,并直观的给出整个项目的测试覆盖情况。此外我们采用其无需改动源码的 On-The-Fly 插桩模式进行部署,可以在系统无感知的情况下,实时的收集代码覆盖率信息。
基于此方案,中通的代码覆盖率服务执行流程大致如下图所示:
如上图所示:
项目发布时,Jacoco 会将探针插桩入项目 jvm 中(用来记录测试人员在执行测试用例(手动/自动化用例)时的代码运行情况);
项目发布完成后,发布平台(stellar)会将本次发布的版本相关信息(比如:git 地址、分支信息、commitid 等)推送给质控平台进行保存;
测试人员在完成测试后,通过质控平台选择分支及代码对比的模式,触发代码覆盖率服务;
代码覆盖率服务通过发布的版本信息从 git 上拉取相应的源码,以及探针获取到的代码覆盖率 dump 文件生成代码覆盖率报告。
此外针对中通实际的业务场景也做了很多功能开发,提高了代码覆盖率系统的易用性:
a. 在发布平台(stellar)发布过程中,用户可以自行选择是否插桩 Jacoco 探针,最终实现了将插桩过程无感知的嵌入到发布流程中;
b. 在质控平台选择发布数据生成报告时,通过对 Jacoco 的二次开发,能够满足测试人员生成全量/增量/分支增量多维度报告的需求。以下详细解释三种生成报告的模式:
全量报告:为选定分支提供全量的代码覆盖率报告。可以为项目整体测试情况提供参考;
分支增量:增量报告的衍生,即当前开发分支 commitid 默认和 master 分支(生产版本)比较,即用于比较当前开发阶段版本与生产版本之间的差异与代码覆盖情况;
增量报告:基于选定两次提交的代码 commitid 之间版本比较,对比差异代码的覆盖率情况。新版本迭代时,通过此模式可以精确掌握代码的变动情况及变动情况的测试覆盖。
c. 以集群的形式挂载了多台执行机,提高执行效率;服务间通过队列方式进行数据传输,提高了数据的可靠性。
目前中通结合代码覆盖率的测试流程如下:
新版本开始后,开发人员在 master 分支上拉取新开发分支(branch1),并在此分支上进行当前版本的功能开发,开发完成并自测通过后发起提测;
测试人员冒烟准入后,根据测试用例进行手工及自动化测试,新功能及改动点测试完毕后生成分支增量覆盖率,并根据报告,针对遗漏功能点,补充执行测试用例;
代码合并主干后,测试人员进行回归测试,并再次获取分支增量覆盖率,针对回归遗漏点,补充执行测试用例;
回归测试通过后,代码封板并上线。
上图以通用配置管理流程举例,实际情况各项目组可能有部分差异。
具体代码覆盖率报告如何使用,我们来看以下例子。
生成的报告如下:
报告中展示被测服务各类不同维度的测试覆盖统计汇总信息
具体点击某类后详情如下,红色代表测试未覆盖代码行
绿色代表测试已覆盖代码行,黄色代表部分覆盖代码行
测试人员根据具体代码染色情况补充测试用例并执行。
在实际运用过程中代码覆盖率在协助发现测试遗漏点及完善测试用例设计的确是能起到很好的辅助作用。此外它也能协助检测出废代码,逆向反推代码设计中的缺陷,提醒开发人员理清代码逻辑,提升代码质量。
目前代码覆盖率服务已经在中通数个部门累计 200 多个服务中试运行。另外根据行业的测试覆盖率要求,测试人员也在朝着语句覆盖率 70%,核心模块的语句覆盖率及分支覆盖率 100% 的目标前进。在接下去的一年中,代码覆盖率服务也会逐渐推广到全中心,为全体测试人员、开发人员提供更好的协助。