jacoco 计算 java 测试覆盖率
2023-06-27
一直以为要计算测试覆盖率有多么复杂, 没想到早就有人提供了一整套工具, 只要配置一下就可以了.
jacoco 使用方法
在 maven pom.xml 里填写jacoco插件, 编译的时候执行测试会自动生成测试覆盖率文件.
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.9</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
编译后的测试文件为 target/jacoco.exec, 不过是二进制文件, 需要专门的工具进行读取. 可以再次执行命令mvn jacoco:report, 会在target/site中生成静态html文件, 这样就能通过浏览器打开查看报告了.
报告支持层级查看, 查看整个package, 某个类, 某个函数. 支持查看行数覆盖率, 分支覆盖率.
分支覆盖率是个不错的概念, 一开始以为是git branch 不太理解, 难道要扫描所有分支? 后面发现其实是对代码里所有的if else和switch分支进行计算, 看有多少分支被测试覆盖到了, 确实是一个很不错的概念.
pom文件里也可以不添加插件, 直接执行下面的命令就可以对任意仓库生成代码覆盖率文件了.
mvn clean test org.jacoco:jacoco-maven-plugin:0.8.5:prepare-agent install -Dmaven.test.failure.ignore=true
参数-Dmaven.test.failure.ignore=true 可以忽略测试过程中的报错, 这样就不需要解决所有test测试的问题后才能进行覆盖率计算.
JaCoCo report generation using maven
https://stackoverflow.com/questions/22836455/jacoco-report-generation-using-maven
参考文件
官方文件
The JaCoCo Maven plug-in provides the JaCoCo runtime agent to your tests and allows basic report creation.
https://www.jacoco.org/jacoco/trunk/doc/maven.html
jacoco 生成单测覆盖率报告
https://www.cnblogs.com/jmcui/p/12843171.html
需要配置 jacoco-maven-plugin 和 maven-surefire-plugin, 防止两方依赖冲突.
- 支持对某些文件进行排除, 避免影响覆盖率. 其中
<includes>或<excludes>标签的值应该是相对于目录/classes/的编译类的类路径(而不是包名),用来指定哪些类需要进行单元测试。 - 支持设置覆盖率目标, 不然无法编译成功.
<properties>
<jacoco.version>0.8.5</jacoco.version>
</properties>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<scope>test</scope>
</dependency>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
-javaagent:${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar=destfile=${project.basedir}/target/coverage-reports/jacoco-unit.exec
</argLine>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
<!--检查代码覆盖率的插件配置-->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<configuration>
<!--指定生成.exec文件的存放位置-->
<destFile>target/coverage-reports/jacoco-unit.exec</destFile>
<!--Jacoco是根据.exec文件生成最终的报告,所以需指定.exec的存放路径-->
<dataFile>target/coverage-reports/jacoco-unit.exec</dataFile>
<includes>
<include>**/service/**</include>
</includes>
<!-- rules里面指定覆盖规则 -->
<rules>
<rule implementation="org.jacoco.maven.RuleConfiguration">
<element>BUNDLE</element>
<limits>
<!-- 指定方法覆盖到50% -->
<limit implementation="org.jacoco.report.check.Limit">
<counter>METHOD</counter>
<value>COVEREDRATIO</value>
<minimum>0.50</minimum>
</limit>
<!-- 指定分支覆盖到50% -->
<limit implementation="org.jacoco.report.check.Limit">
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>0.50</minimum>
</limit>
<!-- 指定类覆盖到100%,不能遗失任何类 -->
<limit implementation="org.jacoco.report.check.Limit">
<counter>CLASS</counter>
<value>MISSEDCOUNT</value>
<maximum>0</maximum>
</limit>
</limits>
</rule>
</rules>
</configuration>
<executions>
<execution>
<id>pre-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
jacoco 包含了多种尺度的覆盖率计数器,包含指令级覆盖(Instructions,C0coverage)、分支覆盖(Branches,C1coverage)、圈复杂度(CyclomaticComplexity)、行覆盖(Lines)、方法覆盖(non-abstract methods)、类覆盖(classes),其含义如下:
- 行覆盖率:度量被测程序的每行代码是否被执行,判断标准行中是否至少有一个指令被执行。
- 类覆盖率:度量计算 class 类文件是否被执行。
- 分支覆盖率:度量 if 和 switch 语句的分支覆盖情况,计算一个方法里面的总分支数,确定执行和不执行的分支数量。
- 方法覆盖率:度量被测程序的方法执行情况,是否执行取决于方法中是否有至少一个指令被执行。
- 指令覆盖:计数单元是单个 java 二进制代码指令,指令覆盖率提供了代码是否被执行的信息,度量完全独立源码格式。
- 圈复杂度:在(线性)组合中,计算在一个方法里面所有可能路径的最小数目,缺失的复杂度同样表示测试案例没有完全覆盖到这个模块。
baeldung: Intro to JaCoCo
baeldung的教程还是非常清晰, 看完大概也清楚基本流程了.