Maven Jacoco 配置 - 从报告中排除 classes/packages 不起作用
Maven Jacoco Configuration - Exclude classes/packages from report not working
我有一个 Maven 多模块项目,我正在使用 jacoco-maven 来生成代码覆盖率报告。有些类不应报告,因为它们是 Spring 配置,我对它们不感兴趣。
我已经声明了 maven-jacoco 插件如下:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.2.201409121644</version>
<configuration>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
<exclude>some.package.*</exclude>
<exclude>**/*Config.*</exclude>
<exclude>**/*Dev.*</exclude>
<exclude>some/package/SomeClass.java</exclude>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
问题是,当我执行 mvn clean verify
时,jacoco 仍然报告应该被排除的类,正如我的 xml 配置指出的那样。如何正确配置它?
您的 XML 有点错误,您需要在排除父字段中添加任何 class 排除项,因此您的上述配置应如下所示 Jacoco docs
<configuration>
<excludes>
<exclude>**/*Config.*</exclude>
<exclude>**/*Dev.*</exclude>
</excludes>
</configuration>
排除字段的值应该是 class 已编译 classes 相对于目录 target/classes/ 使用标准通配符语法的路径(不是包名称)
* Match zero or more characters
** Match zero or more directories
? Match a single character
您也可以这样排除一个包及其所有 children/subpackages:
<exclude>some/package/**/*</exclude>
这将排除 some.package
中的每个 class 以及所有子项。例如,some.package.child
也不会包含在报告中。
我已经测试并且我的报告目标报告了使用上述方法减少的 classes 数量。
如果您随后将此报告推送到 Sonar,则需要告诉 Sonar 在显示中排除这些 classes,这可以在 Sonar 设置中完成
设置 > 常规设置 > 排除项 > 代码覆盖率
Sonar Docs 稍微解释一下
运行 你上面的命令
mvn clean verify
将显示 classes 已被排除
无排除项
[INFO] --- jacoco-maven-plugin:0.7.4.201502262128:report (post-test) @ ** ---
[INFO] Analyzed bundle '**' with 37 classes
有排除项
[INFO] --- jacoco-maven-plugin:0.7.4.201502262128:report (post-test) @ ** ---
[INFO] Analyzed bundle '**' with 34 classes
希望对您有所帮助
https://github.com/jacoco/jacoco/issues/34
这些是 类 的不同表示法,我们有:
- VM 名称:java/util/Map$Entry
- Java 名称:java.util.Map$入口文件
- 姓名:java/util/Map$Entry.class
代理参数、Ant 任务和 Maven 准备代理目标
- 包括:Java 名称(VM 名称也有效)
- 排除:Java 名称(VM 名称也有效)
- exclclassloader: Java 名称
这些规范允许使用通配符 * 和 ?,其中 * 通配符可以是任意数量的字符,甚至可以是多个嵌套文件夹。
Maven 报告目标
- 包括:文件名
- 排除:文件名
这些规范允许 Ant Filespec 像通配符 *、** 和 ? 一样,其中 * 仅是单个路径元素的通配符部分。
虽然安德鲁已经详细回答了问题,但我给出了如何在 pom 中排除它的代码
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<configuration>
<excludes>
<exclude>**/*com/test/vaquar/khan/HealthChecker.class</exclude>
</excludes>
</configuration>
<executions>
<!-- prepare agent for measuring integration tests -->
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
对于Springboot应用
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<excludes>
<!-- Exclude class from test coverage -->
<exclude>**/*com/khan/vaquar/Application.class</exclude>
<!-- Exclude full package from test coverage -->
<exclude>**/*com/khan/vaquar/config/**</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
另一个解决方案:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule implementation="org.jacoco.maven.RuleConfiguration">
<excludes>
<exclude>com.mypackage1</exclude
<exclude>com.mypackage2</exclude>
</excludes>
<element>PACKAGE</element>
<limits>
<limit implementation="org.jacoco.report.check.Limit">
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.85</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
请注意,我们在配置中使用 "<element>PACKAGE</element>"
,这有助于我们在包级别排除。
使用sonar.coverage.exclusions属性。
mvn clean install -Dsonar.coverage.exclusions=**/*ToBeExcluded.java
这应该从覆盖率计算中排除 类。
您可以在 jacoco 插件配置之外的声纳属性中配置覆盖排除:
...
<properties>
....
<sonar.exclusions>
**/generated/**/*,
**/model/**/*
</sonar.exclusions>
<sonar.test.exclusions>
src/test/**/*
</sonar.test.exclusions>
....
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.coverage.exclusions>
**/generated/**/*,
**/model/**/*
</sonar.coverage.exclusions>
<jacoco.version>0.7.5.201505241946</jacoco.version>
....
</properties>
....
并记得从插件中删除排除设置
这是 pom.xml
文件中的工作示例。
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<dataFile>target/jacoco.exec</dataFile>
<!-- Sets the output directory for the code coverage report. -->
<outputDirectory>target/jacoco-ut</outputDirectory>
<rules>
<rule implementation="org.jacoco.maven.RuleConfiguration">
<element>PACKAGE</element>
<limits>
<limit implementation="org.jacoco.report.check.Limit">
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.00</minimum>
</limit>
</limits>
</rule>
</rules>
<excludes>
<exclude>com/pfj/fleet/dao/model/**/*</exclude>
</excludes>
<systemPropertyVariables>
<jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
</plugin>
SonarQube 文档中的一些示例:
这项工作就像 Spring Boot 2.5.3 和 Jacoco 0.8.4 的魅力^_^
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.4</version>
<configuration>
<destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
<dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
<output>file</output>
<append>true</append>
<excludes>
<exclude>**/*com/example/Application.class</exclude>
<exclude>**/*com/example/modal*/**</exclude>
<exclude>**/*com/example/dto*/**</exclude>
<exclude>**/*com/example/mapper*/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
我有一个 Maven 多模块项目,我正在使用 jacoco-maven 来生成代码覆盖率报告。有些类不应报告,因为它们是 Spring 配置,我对它们不感兴趣。
我已经声明了 maven-jacoco 插件如下:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.2.201409121644</version>
<configuration>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
<exclude>some.package.*</exclude>
<exclude>**/*Config.*</exclude>
<exclude>**/*Dev.*</exclude>
<exclude>some/package/SomeClass.java</exclude>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
问题是,当我执行 mvn clean verify
时,jacoco 仍然报告应该被排除的类,正如我的 xml 配置指出的那样。如何正确配置它?
您的 XML 有点错误,您需要在排除父字段中添加任何 class 排除项,因此您的上述配置应如下所示 Jacoco docs
<configuration>
<excludes>
<exclude>**/*Config.*</exclude>
<exclude>**/*Dev.*</exclude>
</excludes>
</configuration>
排除字段的值应该是 class 已编译 classes 相对于目录 target/classes/ 使用标准通配符语法的路径(不是包名称)
* Match zero or more characters
** Match zero or more directories
? Match a single character
您也可以这样排除一个包及其所有 children/subpackages:
<exclude>some/package/**/*</exclude>
这将排除 some.package
中的每个 class 以及所有子项。例如,some.package.child
也不会包含在报告中。
我已经测试并且我的报告目标报告了使用上述方法减少的 classes 数量。
如果您随后将此报告推送到 Sonar,则需要告诉 Sonar 在显示中排除这些 classes,这可以在 Sonar 设置中完成
设置 > 常规设置 > 排除项 > 代码覆盖率
Sonar Docs 稍微解释一下
运行 你上面的命令
mvn clean verify
将显示 classes 已被排除
无排除项
[INFO] --- jacoco-maven-plugin:0.7.4.201502262128:report (post-test) @ ** ---
[INFO] Analyzed bundle '**' with 37 classes
有排除项
[INFO] --- jacoco-maven-plugin:0.7.4.201502262128:report (post-test) @ ** ---
[INFO] Analyzed bundle '**' with 34 classes
希望对您有所帮助
https://github.com/jacoco/jacoco/issues/34
这些是 类 的不同表示法,我们有:
- VM 名称:java/util/Map$Entry
- Java 名称:java.util.Map$入口文件
- 姓名:java/util/Map$Entry.class
代理参数、Ant 任务和 Maven 准备代理目标
- 包括:Java 名称(VM 名称也有效)
- 排除:Java 名称(VM 名称也有效)
- exclclassloader: Java 名称
这些规范允许使用通配符 * 和 ?,其中 * 通配符可以是任意数量的字符,甚至可以是多个嵌套文件夹。
Maven 报告目标
- 包括:文件名
- 排除:文件名
这些规范允许 Ant Filespec 像通配符 *、** 和 ? 一样,其中 * 仅是单个路径元素的通配符部分。
虽然安德鲁已经详细回答了问题,但我给出了如何在 pom 中排除它的代码
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<configuration>
<excludes>
<exclude>**/*com/test/vaquar/khan/HealthChecker.class</exclude>
</excludes>
</configuration>
<executions>
<!-- prepare agent for measuring integration tests -->
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
对于Springboot应用
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<excludes>
<!-- Exclude class from test coverage -->
<exclude>**/*com/khan/vaquar/Application.class</exclude>
<!-- Exclude full package from test coverage -->
<exclude>**/*com/khan/vaquar/config/**</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
另一个解决方案:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule implementation="org.jacoco.maven.RuleConfiguration">
<excludes>
<exclude>com.mypackage1</exclude
<exclude>com.mypackage2</exclude>
</excludes>
<element>PACKAGE</element>
<limits>
<limit implementation="org.jacoco.report.check.Limit">
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.85</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
请注意,我们在配置中使用 "<element>PACKAGE</element>"
,这有助于我们在包级别排除。
使用sonar.coverage.exclusions属性。
mvn clean install -Dsonar.coverage.exclusions=**/*ToBeExcluded.java
这应该从覆盖率计算中排除 类。
您可以在 jacoco 插件配置之外的声纳属性中配置覆盖排除:
...
<properties>
....
<sonar.exclusions>
**/generated/**/*,
**/model/**/*
</sonar.exclusions>
<sonar.test.exclusions>
src/test/**/*
</sonar.test.exclusions>
....
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.coverage.exclusions>
**/generated/**/*,
**/model/**/*
</sonar.coverage.exclusions>
<jacoco.version>0.7.5.201505241946</jacoco.version>
....
</properties>
....
并记得从插件中删除排除设置
这是 pom.xml
文件中的工作示例。
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<dataFile>target/jacoco.exec</dataFile>
<!-- Sets the output directory for the code coverage report. -->
<outputDirectory>target/jacoco-ut</outputDirectory>
<rules>
<rule implementation="org.jacoco.maven.RuleConfiguration">
<element>PACKAGE</element>
<limits>
<limit implementation="org.jacoco.report.check.Limit">
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.00</minimum>
</limit>
</limits>
</rule>
</rules>
<excludes>
<exclude>com/pfj/fleet/dao/model/**/*</exclude>
</excludes>
<systemPropertyVariables>
<jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
</plugin>
SonarQube 文档中的一些示例:
这项工作就像 Spring Boot 2.5.3 和 Jacoco 0.8.4 的魅力^_^
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.4</version>
<configuration>
<destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
<dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
<output>file</output>
<append>true</append>
<excludes>
<exclude>**/*com/example/Application.class</exclude>
<exclude>**/*com/example/modal*/**</exclude>
<exclude>**/*com/example/dto*/**</exclude>
<exclude>**/*com/example/mapper*/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>