【问题标题】:jacoco only shows coverage for classes in the same modulejacoco 仅显示同一模块中的类的覆盖率
【发布时间】:2017-07-07 06:23:36
【问题描述】:

我有一个有点大的多模块 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 工件中的未检测类。这就是为什么我只看到当前模块中的类的覆盖率。

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

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

【问题讨论】:

    标签: java maven powermock jacoco jacoco-maven-plugin


    【解决方案1】:

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

    所有测试还调用其他模块中的其他类

    所以那些没有被检测的。如果我理解正确,那么正是您所缺少的那些。

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

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

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

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

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

    【讨论】:

    • 我想我会用一些中期策略来解决这个问题: 1. 当我们使用带有离线检测的 PowerMock 时,接受模块“foo”中的单元测试只会显示该模块的覆盖率, 2. 在另一个模块中为未涵盖的类编写单元测试, 3. 替换强制使用 PowerMock 使用工厂的一种机制,然后将这些测试更改为使用 Mockito 和在线检测。
    猜你喜欢
    • 2017-05-31
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 1970-01-01
    • 2020-01-14
    相关资源
    最近更新 更多