jacoco仅显示同一模块中的类的覆盖范围

时间:2017-02-17 16:25:49

标签: 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工件的未经检测的类。这就是为什么我只能看到当前模块中类的覆盖范围。

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

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

1 个答案:

答案 0 :(得分:1)

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

  

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

所以没有检测的那些。如果我正确地理解了,那么正是那些你没有覆盖的那些。

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

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

  1. 仪器并运行测试,但不要使用restore-instrumented-classes
  2. 恢复课程并生成报告
  3. 很遗憾,您还没有提供完整的示例(https://stackoverflow.com/help/mcve),而且我没有时间准备完整的示例来测试此方法。

    作为旁注:无法简单地使用代理来自PowerMock绕过任何代理并从磁盘读取类文件的事实。