java - jacoco 仅显示同一模块中类的覆盖率

标签 java maven powermock jacoco jacoco-maven-plugin

我有一个比较大的多模块 Maven 项目。我在 Jacoco 处理的每个模块中都有单元测试。我有一个单独的子模块执行“合并”和“报告聚合”,这似乎正在生成数据。我什至在 SonarQube 中使用生成的数据。我的大部分测试都使用 PowerMock,我使用的是离线检测。

但是,在仔细查看覆盖率数据后,我发现它遗漏了我知道在测试期间正在执行的类和方法的覆盖率数据。我在每个模块中看到的模式是它只报告每个模块中单个类的覆盖率,它实际上是当前模块中的一个类。几乎所有测试还会调用构建中其他模块中的其他类,并且从未报告过这些类的覆盖率。

以下插件配置在每个子模块使用的父pom中:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.8</version>
    <executions>
        <execution>
            <id>default-instrument</id>
            <goals>
                <goal>instrument</goal>
            </goals>
        </execution>
        <execution>
            <id>default-restore-instrumented-classes</id>
            <goals>
                <goal>restore-instrumented-classes</goal>
            </goals>
        </execution>
        <execution>
            <id>default-report</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <argLine>-Xmx1024m</argLine>
        <includes>
            <include>**/*Test.java</include>
        </includes>
        <systemPropertyVariables>
            <jacoco-agent.destfile>${project.build.directory}/jacoco.exec</jacoco-agent.destfile>
            <running-unit-test>true</running-unit-test>
        </systemPropertyVariables>
    </configuration>
</plugin>

当我检查为每个模块生成的 HTML 结果时,我发现它只报告当前模块中单个类的结果,而不报告其他模块中类的数据。由此,我假设我在单独的子模块中如何进行“合并”和“报告聚合”可能与这个问题无关。

生成的“jacoco.exec”文件是二进制文件,但我尝试从一个模块中“剔除”一个文件,只是为了查看可见的 ascii 文本,它只显示了一次看起来像文件名的内容,并且它是该模块的 HTML 覆盖率报告中报告的唯一文件名。

我不确定我可以报告哪些其他信息。

更新:

我想我现在可以很清楚地看到,当 surefire 运行单元测试时,它使用当前模块中的检测类,但使用 Maven Artifact 中的未检测类。这就是为什么我只看到当前模块中类的覆盖率。

所以我似乎需要一种方法来指定当前模块所依赖的每个模块的“target/generated-classes/jacoco”文件夹添加到 surefire 使用的类路径之前。我看不到这样做的方法。

或者,我看到“instrument”目标有一个“includes”配置元素。我是否应该为当前模块所依赖的每个模块指定所有“目标/类”目录的路径?

最佳答案

记录某些类的代码覆盖率需要它的检测。目标 instrument 执行当前模块类的检测。

all of the tests also call out to other classes in other modules

所以那些没有检测的。如果我的理解正确,那么正是您遗漏的内容。

如果您不对来自其他模块的类使用 PowerMock,而只对当前模块中的类使用 PowerMock,那么您可以使用代理将离线检测与即时检测结合起来。但在这种情况下,请确保离线检测的类被代理明确排除在检测之外,否则代理将抛出 IllegalStateException: Class ... is already instrumented

如果您对来自其他模块的类使用 PowerMock,那么由于 Maven 在类路径和依赖项操作方面的严格性,这会变得更加复杂。我怀疑使用一个 mvn 命令是否可以轻松实现这一点,但是使用更多似乎是可能的:

  1. 检测并运行测试,但不要使用 restore-instrumented-classes
  2. 恢复类(class)并生成报告

很遗憾,您没有提供完整的示例 (https://stackoverflow.com/help/mcve),我现在没有时间准备完整的示例来测试这种方法。

附带说明:无法简单地使用代理是因为 PowerMock 会绕过任何代理并从磁盘读取类文件。

关于java - jacoco 仅显示同一模块中类的覆盖率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42302786/

相关文章:

java - 使用 Tycho/Maven 构建 RAP 会出现 DuplicateReactorIUsException

eclipse - PowerMock 和 Robolectric 的 ExceptionInInitializerError

java - Antlr主类错误: MyListener cannot be resolved to a type

java - 在 Hadoop 中映射应用程序

maven - 使用 pom 文件从目标目录中删除或删除资源文件

java - junit 重新加载类

java - dropwizard + Powermock + Mockito + Maven 构建错误,出现 ClassNotFoundException "ThreadSafeMockingProgress"

java - 使用一个 JComboBox 控制另一个 Jcombobox

java - 如何使一个有弹性的物体从另一个物体上弹得更低?

java - org.springframework.beans.factory.BeanCreationException : NoClassDefFoundError: Could not initialize class org. hibernate.ann