EZLippi-浮生志

利用Jacoco计算单元测试覆盖率

随着敏捷开发的流行,编写单元测试已经成为业界共识。TDD(测试驱动开发)的思想也强调了测试的重要性,怎么去衡量我们的测试代码的质量呢,常见的办法就是计算测试的覆盖率,常见的Java的覆盖率计算工具有JCov、Cobertura和Jacoco,三者都支持对class文件离线插桩,JCov和Jacoco还支持动态插桩,单元测试和集成测试都无法在模拟真实的运行环境,存在一定的局限性。

最近开发组这边提出了一个新的任务,要能够在真实的环境中验证一些核心逐组件的功能,并得出测试代码的覆盖率,很快环境就搭建起来,把要测试的一些接口和服务注册在服务总线上,客户端通过Rest请求相应的服务,在被测机上安装好插桩工具,实现覆盖率的收集。这篇文章主要记录Jacoco的Maven配置,方便日后查阅。

配置JaCoCo Maven插件

使用Jacoco Maven插件主要基于两个考虑:

  1. 通过Maven插件能够访问Jacoco运行时agent
  2. Jacoco runtime agent创建的数据可以生成覆盖率报告

主要有以下两步:

  1. 配置Maven Jacoco插件依赖
  2. 为单元测试配置覆盖率报告

配置Jacoco插件

代码如下:

1
2
3
4
5
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
</plugin>

为单元测试配置覆盖率报告

主要配置两个execution,第一个创建一个执行Jacoco运行时Agent的属性,确保覆盖率数据写入到target/coverage-reports/jacoco-ut.exec文件中,属性名称为surefireArgLine,当我们运行单元测试时这个属性传递给JVM参数。

第二个execution配置单元测试运行之后生成覆盖率报告,报告写在target/site/jacoco-ut文件。具体配置代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<executions>
<!--
准备指向Jacoco运行时Agent的属性,在测试执行之前传递给虚拟机参数
-->

<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<!-- 设置覆盖率数据文件路径 -->
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
<!-- 设置属性名称,Maven surefire插件需要引用这个作为命令行参数
-->

<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<!--
确保在单元测试执行之后生成覆盖率报告
-->

<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- 引用覆盖率文件的路径-->
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<!-- 设置覆盖率报告存放路径. -->
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

配置Maven surefire插件

之所以使用Surefire插件来执行单元测试是想确保我们运行测试代码的时候Jacoco Agent能够运行,做法就是把上面的surefireArgLine属性传递给surefire命令行参数,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.15</version>
<configuration>
<!-- 设置虚拟机参数 -->
<argLine>${surefireArgLine}</argLine>
<!-- 排除集成测试的代码. -->
<excludes>
<exclude>**/IT*.java</exclude>
</excludes>
</configuration>
</plugin>

生成覆盖率报告

运行maven clean test命令后就在target/site/jacoco-ut生成了覆盖率报告。

参考文献: Jacoco Maven文档

🐶 您的支持将鼓励我继续创作 🐶