maven-surefire-plugin+Jacoco选择性统计代码覆盖率
问题背景
本文以maven项目为例,主要解决一下两个问题:
- 在代码构建时不想执行测试代码,或者希望有选择地执行其中一部分测试代码
- 使用jacoco插件生成覆盖率测试报告,并且只统计已选择执行的部分测试代码的覆盖率
maven-surefire-plugin插件
Maven构建项目的生命周期分为很多个阶段,其中test阶段默认绑定了maven-surefire-plugin插件来执行JUnit或TestNG的测试用例。
也就是说,当执行 mvn test 命令时,maven-surefire-plugin插件就已经开始工作了。
maven-surefire-plugin插件可以通过一些属性配置来选择性地执行指定的测试类,默认情况下,surefire插件会自动执行 src/test/ 目录下符合以下命名规则的测试类:
1) Test*.java: 任何以 Test 开头的Java类
2) *Test.java: 任何以 Test 结尾的Java类
3) *TestCase.java: 任何以 TestCase 结尾的Java类
maven-surefire-plugin插件的导入:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
</plugin>
跳过全部测试用例
- 如果需要跳过所有的测试代码,可以使用 <skipTests>true</skipTests> 进行配置
- 默认不跳过测试,即 <skipTests>false</skipTests>
- 对于包含多个子工程的项目,在父pom.xml配置 <skipTests>true</skipTests> 属性,则所有的子工程的测试代码都跳过执行;若某个子工程也配置surefire插件并将该属性设为false,则盖子工程不会跳过其测试代码的执行
- maven-surefire-plugin生成的测试报告默认存放在工程的 ${basedir}/target/surefire-reports/ 路径下,${basedir} 是 pom.xml 文件所在的目录;对于多工程的项目,每个工程的target目录先都会生成 surefire-reports
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
跳过测试在控制台会显示 [INFO] Tests are skipped. 信息,同时由于无法生成 jacoco.exec 文件,jacoco也无法生成覆盖率报告。
跳过部分测试代码
- surefire插件通过配置
<include>和<exclude>属性来选择执行或不执行某些指定的测试用例,最终执行的测试代码是两者的交集 - 例如,下面代码中,最终会执行所有类名以 Test 结尾的测试类,并且不执行所有类名以 TestCase 结尾的测试类
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<includes>
<include>**/*Test.class</include>
<exclude>**/*Test.class</exclude>
</includes>
<excludes>
<exclude>**/*TestCase.class</exclude>
</excludes>
</configuration>
</plugin>
<include> 和 <exclude> 可以通过 **、*、? 来匹配相应的类名
<include> 和 <exclude> 中匹配的是包路径,不能使用类似 /home/ubuntu/project/project-demo/src/test/org/example/CalculateTest.class 这种绝对路径
**: 匹配零个或多个目录
*: 匹配零个或多个字符
?: 匹配单个字符
<include> 和 <exclude> 具体配置示例:
<include>CalculateTest</include> -->指定具体类名
<include>CalculateTest.java</include> -->指定具体测试类的文件
<include>CalculateTest.class</include> -->指定具体类名
<include>**/*Test.class</include> -->匹配所有类名以 Test 结尾的测试类
<include>**/example/**/*</include> -->匹配所有包路径中包含 example 的测试类
Jacoco生成覆盖率报告
maven-surefire-plugin插件使用 <skipTests>true</skipTests> 或者 <include>、<exclude> 配置可以跳过或者选择指定的测试类,但在使用Jacoco统计覆盖率是,实际上那些被指定跳过的代码也还是会被统计进来的。
例如,假设有三个类 TestA、 TestB、 TestC,分别有 20 、30、50行代码,共100行,现在使用surefire插件设置跳过TestB和 TestC 的测试代码,只执行 TestA 的测试代码。那么,即使 TestA 的20行代码全部被覆盖到,最终Jacoco统计的行覆盖率仍然只有20%,因为Jacoco默认统计项目的所有代码的行覆盖率。
如果全部跳过测试,Jacoco将无法生成 jacoco.exec 文件,则会显示 [INFO] Skipping JaCoCo execution due to missing execution date file. 信息。
如果希望在跳过TestB和 TestC 的测试代码的同时,让Jacoco只对 TestA 进行统计,则需要进行相应的配置。
Jacoco插件导入
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.1</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
配置 <include> 和 <exclude> 属性,选择指定的测试代码进行jacoco统计:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.1</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<!-- 对包路径中包含example的所有测试类进行jacoco统计 -->
<include>**/example/**/*</include>
</includes>
<excludes>
<!-- 排除包路径中包含util的所有测试类进行jacoco统计 -->
<exclude>**/util/**/*</exclude>
</excludes>
</configuration>
</plugin>
当然,Jacoco生成覆盖率报告的前提是能够正常地生成jacoco.exec文件,该文件默认保存在 ${basedir}/target/ 路径下。
Jacoco生成的覆盖率报告默认保存在 ${basedir}/target/site/jacoco/ 路径下。
总结
通过结合使用 maven-surefire-plugin 插件和 Jacoco,可以在构建项目时只执行指定的测试代码,并且只统计指定的测试代码的jacoco覆盖率,方便代码开发调试。
————————————————
版权声明:本文为CSDN博主「maplelpc」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44096248/article/details/121005420
更多推荐
所有评论(0)