Maven Jacoco配置 - 排除类/包不在报告中生效

147

我有一个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配置也指出了这一点。如何正确配置它?

问题是,当我执行mvn clean verify时,Jacoco仍然报告了应该被排除的类,即使我的XML配置已经指明了这一点。如何正确地进行配置?

9个回答

239
您的XML稍有错误,您需要在“excludes”父字段中添加任何类别的例外,因此根据Jacoco文档,您上述的配置应该像以下这样。
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.8</version>
    <configuration>
        <excludes>
            <exclude>**/*Config.*</exclude>
            <exclude>**/*Dev.*</exclude>
        </excludes>
    </configuration>
    <executions>
        <execution>
            <id>jacoco-report</id>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

排除字段的值应该是相对于目录 target/classes/ 的已编译类的类路径(而不是包名),使用标准通配符语法。

*   Match zero or more characters
**  Match zero or more directories
?   Match a single character
您也可以通过以下方式排除一个包及其所有子包/子包:

您也可以通过以下方式排除一个包及其所有子包/子包:

<exclude>some/package/**/*</exclude>

这将排除some.package中的每个类,以及任何子类。例如,some.package.child也不会包含在报告中。

我已经测试并使用上述方法减少了所报告类的数量。

如果您要将此报告推送到Sonar中,则需要告诉Sonar在显示中排除这些类,可以在Sonar设置中完成。

设置 > 通用设置 > 排除 > 代码覆盖率

Sonar文档对此进行了更详细的说明。

运行您上面的命令

mvn clean verify

将显示已排除的类

无排除

[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

2
我不得不将Jacoco插件从0.7.5版本升级到0.7.6版本,以便排除被考虑在内。 - Stephane
2
关于 Sonar 的技巧很棒。很容易假设 JaCoCo 的排除会自动传播到 Sonar(就像我一样)。 - markdsievers
16
如果我从Jacoco中排除一个文件,它会在覆盖率报告中显示为0%的覆盖率。所以基本上相比于不排除文件,我的结果变差了。这个问题可以解决吗? - Adam Arold
6
请记得在文件名之间使用斜杠而不是点号。此外,文件的后缀名应为.class而非.java。 - ThomasRS
1
重要的是要理解 ** 和 * 的影响。如果不包括 *,它就不会遍历到底层目录。 是一个单个字符,应该用于文件名的目的。 - Smart Coder
显示剩余9条评论

28

虽然Andrew已经详细回答了问题,但我提供一个在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>

3
看起来类路径应该 不带 .class 结尾,例如:<exclude>**/*com/test/vaquar/khan/HealthChecker</exclude> - hovenko
10
这将从报告中完全删除该软件包: <exclude>com/mycompany/mypackage/**/*</exclude> - Jim Tough
为什么要使用 **/*com 而不是 **/com - Ivan
@JimTough只需要从执行文件中删除软件包,而不从报告中删除。 - Mehul Parmar

6
您可以在 Sonar 属性中配置覆盖率排除项,而不是在 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>
....

还要记得从插件中删除排除设置


5

以下是SonarQube文档中的一些示例: 在此输入图片描述


5

另一个解决方案:

<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>"来帮助我们在包级别上进行排除。

我正在使用jacoco-maven-plugin:0.7.9。通过您的解决方案,它可以正确计算结果。但是,项目中的所有类都出现在jacoco报告(index.html)中。是否有可能仅显示插件分析的内容以获得覆盖率的真实值? - aloplop85

4

此方法在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>

4
请使用 sonar.coverage.exclusions 属性。
mvn clean install -Dsonar.coverage.exclusions=**/*ToBeExcluded.java

这将排除类的覆盖率计算。

3

https://github.com/jacoco/jacoco/issues/34

下面是我们使用的不同类标记:

  • VM名称:java/util/Map$Entry
  • Java名称:java.util.Map$Entry 文件
  • 名称:java/util/Map$Entry.class

代理参数、Ant任务和Maven prepare-agent目标

  • 包括:Java名称(VM名称也可以)
  • 排除:Java名称(VM名称也可以)
  • exclclassloader: Java名称

这些规范允许使用通配符 * 和 ?,其中 * 通配任意数量的字符,甚至多层嵌套的文件夹。

Maven报告目标

  • 包括:文件名
  • 排除:文件名

这些规范允许使用 Ant 文件规范中的通配符 *、** 和 ?,其中 * 仅通配单个路径元素的一部分。


1
这是在 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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接