我们项目中使用powerMock作为单元测试的mock工具,统计项目测试覆盖率使用jacoco编译的结果上传到sonar,但是jacoco 和 powerMock在运行时runtime加载代码的时候自定义了类加载器,所以就会有冲突,导致测试覆盖率为0。
使用命令 mvn clean verify sonar:sonar上传jacoco编译结果(这里sonar命令会自动调用jacoco-maven-plugin插件编译),出现错误:
[WARNING] Classes in bundle 'MyDemoProject' do not match with execution data. For report generation the same class files must be used as at runtime.
[WARNING] Execution data for class com/demo/controller/DemoController does not match.
问题定位:运行时加载类出现问题
解决问题:
找到jacoco 官方文档描述:https://www.eclemma.org/jacoco/trunk/doc/classids.html
其中:
What happens if different classes are used at runtime and at analysis time?
In this case execution data cannot be related to the analyzed classes. As a consequence such classes are reported with 0% coverage.
What can cause different class ids?
Even if the class files on the file system are the same there is possible that classes seen by the JaCoCo runtime agent are different anyways. This typically happens when another Java agent is configured before the JaCoCo agent or special class loaders pre-process the class files. Typical candidates are:
- Mocking frameworks
- Application servers
- Persistence frameworks
上面清晰的描述了测试覆盖率为0的原因,和使用mock框架的影响。
解决方式参考:https://www.eclemma.org/jacoco/trunk/doc/examples/build/pom-offline.xml
最终pom 正确配置如下:
<properties>
<jacoco.version>0.8.8</jacoco.version>
</properties>
<dependencies>
<dependency>
<!-- must be on the classpath -->
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<classifier>runtime</classifier>
<version>${jacoco.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<jacoco-agent.destfile>${basedir}/../target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<configuration>
<destFile>${basedir}/../target/jacoco.exec</destFile>
<dataFile>${basedir}/../target/jacoco.exec</dataFile>
<output>file</output>
<append>true</append>
</configuration>
<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>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<build>
<plugins>
说明:文章来源:https://www.toymoban.com/news/detail-403388.html
上面的pom.xml是多模块项目中的父pom,其中jacoco.exec需要包含所有子模块的扫描结果,所以配置的路径是:${basedir}/../target/jacoco.exec(所有子模块的结果都是存放在父(根)目录下的target目录中),并且设置了 <append>true</append> 所有子模块生成一个jacoco.exec文件中。文章来源地址https://www.toymoban.com/news/detail-403388.html
到了这里,关于java & jacoco & powerMock 单元测试覆盖率为0怎么解决的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!