maven构建中的代码覆盖率-由于缺少类目录,正在跳过JaCoCo执行



如果我只有一个项目,但现在我有一个多模块项目,我可以让代码覆盖率正常工作。

我的应用程序是在api项目中构建的,我的所有集成测试都在一个单独的项目中运行,该项目使用作为上一个模块构建的工件。

构建运行,但我没有得到代码覆盖率报告,相反,我得到了信息消息:

Skipping JaCoCo execution due to missing classes directory

我的覆盖率报告文件jacoco-it.exec已经创建,但jacoco插件似乎需要运行测试的项目中的类

有人能告诉我,当类在另一个模块中时,我需要做什么才能创建覆盖率报告吗?

经过反复试验,我设法找到了一种变通方法。

看起来jacoco插件很乐意创建没有类的exec文件,但如果没有类,它就不会创建报告,我不明白jacoco内部是如何工作的,所以如果有人知道,你能解释一下吗?

我也不确定我所做的是否可靠,但它似乎确实报告了我的硒驱动测试的覆盖范围。

我自己提出的(可能的)解决方案是使用maven资源插件复制从我的target\cargo中的war文件中分解的类。。目录中的目标\类:

<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>copy-resources</id>             
<phase>pre-integration-test</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<resources>          
<resource>
<directory>${basedir}/target/cargo/configurations/tomcat7x/webapps/calculator-api/WEB-INF/classes</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*Config*.*</exclude>
<exclude>**/*Initialiser*.*</exclude>
</excludes>
</resource>
</resources>              
</configuration>            
</execution>
</executions>
</plugin>

这似乎让jacoco插件很开心,我得到了我的代码覆盖率,尽管插件现在似乎忽略了我的排除列表。

有人知道这是否真的是一个解决方案吗?它"似乎"有效,但我在网上找不到推荐的方法,我也不确定为什么jacoco代理设置上的排除选项似乎不再有效。

我已经设法绕过了jacoco插件,不排除文件,只是不使用资源插件复制它们,但我仍然不了解jacoco是如何工作的。

即使jacoco:report-aggregate用于依赖项的聚合报告,它在我的情况下也不起作用-我使用的项目结构如下:

project
└─ module-api   ⇦ API definition
└─ module-spec  ⇦ module with black box tests through the API
└─ module-impl1 ⇦ implementation 1 of the API
└─ module-impl2 ⇦ another implementation of the API
└─ module-test1 ⇦ some dependencies + impl1, apply the tests from spec
└─ module-test2 ⇦ some dependencies + impl2, apply the tests from spec

在这种情况下,report-aggregate生成了一个空报告。module-test1和module-test2项目具有POM封装类型,这也不适合在它们上运行report,因为它需要target/classes目录中的类。

我的解决方案

我将jacoco插件配置为将其插入的类转储到项目的target/classes目录中,方法是添加:<classDumpDir>${project.build.outputDirectory}</classDumpDir>

这使得report的常规目标得以实现。完整的代码是:

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<configuration>
<destFile>${project.build.directory}/coverage-reports/code-coverage.exec</destFile>
<dataFile>${project.build.directory}/coverage-reports/code-coverage.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/code-coverage</outputDirectory>
<propertyName>jacocoArgLine</propertyName>
<classDumpDir>${project.build.outputDirectory}</classDumpDir>
</configuration>
<executions>
<execution>
<id>prepare-jacoco-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-integration-test</id>
<phase>post-integration-test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>

请注意,插入指令的类来自所有依赖项,因此需要进行一些筛选以缩小报告范围。请参阅:https://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html

我有类似的项目结构-主代码在一个模块中,在另一个模块进行测试-并且在jacoco报告中遇到了类似的问题。

我的解决方案1

只需通过maven-resources-plugin/classes文件夹复制到测试模块即可。

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-classes-to-test-module</id>
<goals>
<goal>testResources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${project.basedir}/../main-module/target/classes</directory>
</resource>
</resources>
<outputDirectory>
${project.build.outputDirectory}
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

但是,如果您的代码包含Lambda、匿名类等,那么结果报告可能不会覆盖某些类,因为由于prepare-agent运行的不同,它将是不同的类。

我的解决方案2:

使用report-aggregate目标。

在父POM中,我有这样的配置:

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.3</version>
<configuration>
<append>true</append>
</configuration>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>

测试模块的POM包含以下行:

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report-aggregate</goal>
</goals>
</execution>
</executions>
</plugin>

请记住,依赖范围对于report-aggregate目标(jacoco-docs)非常重要。如果您的测试模块只有测试范围的依赖项,则会得到一个空报告。因此,您应该将范围设置为编译、运行时或为那些工件提供,您希望在报告中看到这些工件。例如:

<dependency>
<groupId>my.project</groupId>
<artifactId>main-module-classes</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>

您可以使用目标jacoco:report-aggregate,它正是为在单独的测试模块中创建覆盖率报告而设计的。

这里有一个例子:

project
└─ module      ⇦ module with sources
└─ module-test ⇦ module with tests

然后你所要做的就是在"模块测试"的pom.xml中使用这个目标:

<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>jacoco-report-aggregate</id>
<phase>verify</phase>
<goals>
<goal>report-aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

另外,要小心文档中提到的依赖关系中使用的作用域。

最新更新