Maven Jacoco 配置 - 从报告中排除类/包不起作用

Posted

技术标签:

【中文标题】Maven Jacoco 配置 - 从报告中排除类/包不起作用【英文标题】:Maven Jacoco Configuration - Exclude classes/packages from report not working 【发布时间】:2015-03-04 03:57:25 【问题描述】:

我有一个 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 配置所指出的那样。如何正确配置?

【问题讨论】:

【参考方案1】:

您的 XML 有点错误,您需要在 excludes 父字段中添加任何类排除项,因此根据Jacoco docs,您的上述配置应如下所示

<configuration>
    <excludes>
        <exclude>**/*Config.*</exclude>
        <exclude>**/*Dev.*</exclude>
    </excludes>
</configuration>

排除字段的值应该是使用标准通配符语法相对于目录 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 Docs 再解释一下

在上面运行你的命令

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

希望对你有帮助

【讨论】:

我必须将 Jacoco 插件从 0.7.5 版升级到 0.7.6 版才能考虑到排除。 关于声纳的好建议。很容易假设 JaCoCo 排除会自动传播到声纳(就像我一样)。 如果我排除 jacoco 格式的文件,它会以 0% 的覆盖率显示在覆盖率报告中。所以基本上我得到的结果比不排除更差。这可以解决吗? 记得在文件名之间使用斜线而不是点。此外,文件结尾是 .class 而不是 .java。 了解**和*的影响很重要。如果您不包含 ** ,那么它将不会遍历到底层目录。 * 是单个字符,应用于文件名。【参考方案2】:

虽然 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>

【讨论】:

嗨 Vaquar,我一直在为通过 jacoco maven 插件排除软件包而苦恼。我不想在创建的 Index.html 上显示排除的包。如果你有代码,你可以做同样的事情,请帮助我。将代码发送至 imvrajendra@gmail.com 看来类路径应该没有.class结尾,如:&lt;exclude&gt;**/*com/test/vaquar/khan/HealthChecker&lt;/exclude&gt; 这会为我从报告中删除整个包:​​&lt;exclude&gt;com/mycompany/mypackage/**/*&lt;/exclude&gt; 为什么是**/*com 而不仅仅是**/com【参考方案3】:

另一种解决方案:

<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>

请注意,我们在配置中使用"&lt;element&gt;PACKAGE&lt;/element&gt;",这有助于我们在包级别排除。

【讨论】:

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

您可以在声纳属性中配置覆盖排除,在 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】:

使用 sonar.coverage.exclusions 属性。

mvn clean install -Dsonar.coverage.exclusions=**/*ToBeExcluded.java

这应该从覆盖率计算中排除类。

【讨论】:

【参考方案6】:

SonarQube 文档中的一些示例:

【讨论】:

【参考方案7】:

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

这些是我们拥有的类的不同表示法:

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

代理参数、Ant 任务和 Maven 准备代理目标

包括:Java 名称(VM 名称也可以) 不包括:Java 名称(VM 名称也可以) exclclassloader:Java 名称

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

Maven 报告目标

包括:文件名 不包括:文件名

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

【讨论】:

【参考方案8】:

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

【讨论】:

【参考方案9】:

这项工作就像 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 配置 - 从报告中排除类/包不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Jacoco配置-从报告中排除类/程序包

Jacoco配置-从报告中排除类/程序包

Jacoco配置-从报告中排除类/程序包

Jacoco配置-从报告中排除类/程序包

使用Sonarrunner和Gradle从Jacoco报告中排除软件包

如何从android项目中的jacoco测试覆盖率报告中排除方法