基于Jacoco的三种增量覆盖率统计方法

2024-04-28 16:50:53 浏览数 (3)

本文介绍三种基于Jacoco的增量代码覆盖率统计方法,并给出了对应的四种对应的开源工具。

以下是Jacoco覆盖率统计的工作流程示意图。增量覆盖率的计算过程可以理解为对覆盖率结果进行一次减法计算得到的差值。

既然是减法,就需要减数和被减数两方。而减法执行的时机,可以是上图 中的多个节点,即

1)在 agent 打桩时只针对增量部分进行打桩,或者是在全量覆盖率统计完成后,将生成的 jacoco.exec 覆盖率文件解析

2)生成可读的覆盖率统计报告的环节进行增量计算。

3)此外,还可以在报告生成后,通过解析xml/html 格式的文件来生成增量覆盖率。

当然,上述 1-3 方案都需要借助于代码变动分析的结果作为输入。

除了上述方案外,也可以通过 Sonar Scanner 对单次执行结果进行扫码,借助于SonarQube 等质量平台的能力得到增量覆盖率结果,也就是方案 4。从原理上来讲,这个方案与方案3是等价的。因此也可以归为3)。

接下来将逐一对上述方案做简要的介绍。

  • 方案1 -Agent插桩时

Jacoco 在进行 prepare-agent 时,接受调用者通过使用 excludes 参数来忽略某些类,例如可以该方式来自动忽略 Lombok 自动生成的代码,避免统计结果中的代码膨胀。类似的,可以通过includes 参数来只针对指定的类和方法进行打桩。

这是增量覆盖率统计的技术基础,原理是在 jacoco 进行打桩时,结合 git-diff 产生的增量清单作为 includes 的入参,让 jacoco 只针对指定的需要进行覆盖率统计的代码进行打桩,也就是只针对增量代码进行打桩。其后再生成的覆盖率统计报告自然而然就是增量的报告了。

开源项目如滴滴开源的 super-jacoco就是采用了这种方案,并对原生的 jacoco 进行了功能增强,形成的覆盖率统计平台。对于单元测试来说,可以通过一个 HTTP 请求来完成整个代码下载、构建、单元测试和增量/全量报告生成。用户可以通过查询接口,根据先前自行指定的任务UUID 来查询上述接口。

当然,这个方案中,由于修改了打桩范围的原因,不能同时生成全量和增量的覆盖率结果,需要分两次执行。

  • 方案2-Jacoco报告生成时

Agent 增量打桩的方案,主要专注于增量覆盖率统计的场景,对于全量、增量均需要产生覆盖率的情况,就需要另外的解决方案了。code-diff这个开源项目就是使用了另外一种方案,即在调用 jacoco 命令行解析 jaocco.exec 生成 xml/html 覆盖率报告时,附加额外的 git-diff 代码增量清单,进而可以生成增量覆盖率统计报告。如果没有提供 git-diff 清单,则可以生成全量的覆盖率报告。因此只要针对同一个 jacoco.exec 覆盖率文件执行两次解析和报告生成的操作,就能得到全量和增量的两份结果。

  • 方案3-解析Jaococo报告

在打桩和报告环节对 jacoco 进行改造,进而形成的增量覆盖率方案,都需要对 jacoco 进行二次开发,技术门槛相对较高,且后续 Jacoco 发行新的版本,二次开发的版本也需要额外进行升级维护。此外如果目标项目中已经引入了 jacoco 开展了单元测试覆盖率统计,还牵涉到如何说服用户配合去修改既有的 jacoco 配置以适配二次开发后的 jacoco 工具的问题,存在推广实施上的门槛。

由此,产生了第三种方案,即通过解析业已生成的 xml/html 覆盖率报告,并结合 git-diff 结果来计算生成增量覆盖率报告。笔者所在团队的增量覆盖率统计服务也采用了该方案。由于这个方案主要涉及到最终结果的解析,不对用户团队已有的 jacoco 使用有变更要求,更利于这个方案的推广实施。

开源的增量覆盖率统计工具 diff-cover就是采用了该方案。这个工具原先主要用于分析 C 覆盖率统计报告,经过笔者提的需求之后,已经支持了对 jacoco 报告的解析从而可以用于 Java项目的增量覆盖率统计。

而著名的SonarQube也是采用的这个方案。

  • 总结一下

本文介绍三种基于Jacoco的增量代码覆盖率统计方法,并给出了对应的四种开源工具。

方案

开源工具

全量 增量覆盖率报告

1

Agent插桩时

Super-Jacoco

执行两次用例

2

Agent report时

Code-Diff

执行一次用例执行两次报告生成

3

Report解析

Diff-CoverSonarQube

执行一次用例执行一次报告生成

你学废了吗?

0 人点赞