我使用jacoco:report标签生成jacoco报告。 我收到的错误如下:
[jacoco:report] Classes in bundle 'Code Coverage Report' do no match with execution data. For report generation the same class files must be used as at runtime.
[jacoco:report] Execution data for class xxxxx does not match.
[jacoco:report] Execution data for class yyyyy does not match.
蚂蚁报告目标如下:
<target name="report">
<jacoco:report>
<executiondata>
<file file="${jacocoexec.dir}/${jacocoexec.filename}"/>
</executiondata>
<!-- the class files and optional source files ... -->
<structure name="Code Coverage Report">
<classfiles>
<fileset file="./jar/abc.jar"/>
</classfiles>
<sourcefiles>
<fileset dir="./code/src"/>
</sourcefiles>
</structure>
<!-- to produce reports in different formats. -->
<html destdir="${jacoco.report.dir}"/>
</jacoco:report>
</target>
如此生成的abc.jar
仅使用./code/src
。那么为什么会出现这样的错误呢。有什么想法吗?
答案 0 :(得分:20)
您收到与classID相关的错误。这是JaCoCo docs-site详细描述的概念。 http://www.eclemma.org/jacoco/trunk/doc/classids.html。这是在同一JVM中支持多个版本的类(例如appserver)的关键步骤。
将部分内容复制到此处以查看可见性。
什么是类ID以及它们是如何创建的?
类ID是64位整数值,例如0x638e104737889183 in 十六进制表示法。他们的计算被认为是一个实现细节 JaCoCo。目前使用原始的CRC64校验和创建ID 类文件。
什么可能导致不同的类ID?
类ID对于完全相同的类文件是相同的 (逐字节)。你可能会得到几个原因 不同的类文件。首先编译Java源文件 在不同的类文件中,如果您使用不同的工具链:
不同的编译器供应商(例如Eclipse与Oracle JDK)
不同的编译器版本
不同的编译器设置(例如,调试与非调试)
后处理类文件(混淆,AspectJ等)通常也会更改类文件。如果您只是为运行时和分析使用相同的类文件,JaCoCo将运行良好。因此,创建这些类文件的工具链并不重要。
即使文件系统上的类文件相同,JaCoCo运行时代理程序看到的类也可能不同。这通常发生在JaCoCo代理或特殊类加载器预处理类文件之前配置另一个Java代理时。典型的候选人是:
同一页面涵盖了可能的解决方案。
处理运行时修改的类有哪些变通方法?
如果在您的设置中运行时修改了类,那么有一些解决方法可以让JaCoCo继续工作:
于2017年2月22日编辑
如何使用离线工具: 使用Daniel Atallah提供的以下任务。
//Additional SourceSets can be added to the jacocoOfflineSourceSets as needed by
project.ext.jacocoOfflineSourceSets = [ 'main' ]
task doJacocoOfflineInstrumentation(dependsOn: [ classes, project.configurations.jacocoAnt ]) {
inputs.files classes.outputs.files
File outputDir = new File(project.buildDir, 'instrumentedClasses')
outputs.dir outputDir
doFirst {
project.delete(outputDir)
ant.taskdef(
resource: 'org/jacoco/ant/antlib.xml',
classpath: project.configurations.jacocoAnt.asPath,
uri: 'jacoco'
)
def instrumented = false
jacocoOfflineSourceSets.each { sourceSetName ->
if (file(sourceSets[sourceSetName].output.classesDir).exists()) {
def instrumentedClassedDir = "${outputDir}/${sourceSetName}"
ant.'jacoco:instrument'(destdir: instrumentedClassedDir) {
fileset(dir: sourceSets[sourceSetName].output.classesDir, includes: '**/*.class')
}
//Replace the classes dir in the test classpath with the instrumented one
sourceSets.test.runtimeClasspath -= files(sourceSets[sourceSetName].output.classesDir)
sourceSets.test.runtimeClasspath += files(instrumentedClassedDir)
instrumented = true
}
}
if (instrumented) {
//Disable class verification based on https://github.com/jayway/powermock/issues/375
test.jvmArgs += '-noverify'
}
}
}
test.dependsOn doJacocoOfflineInstrumentation
现在使用"gradlew test jacocoTestReport"
命令生成报告。
答案 1 :(得分:6)
JaCoCo需要与执行时使用的报告生成完全相同的类文件。由于编译器和/或修改类的其他工具不同,这些类可能会有所不同。
答案 2 :(得分:2)
我注意到,如果您要报告其代码覆盖率的类的静态初始化被 Mockito 和 PowerMockito 在您的 JUnit 测试中抑制,则会发生这种情况。例如,如果您的测试类如下所示:
@SuppressStaticInitializationFor(
{"com.yourpkg.A",
"com.yourpkg.B"})
public class Test {
@Test
public void Test() { }
}
测试时的错误类似于:
Classes in bundle 'yourProject' do not match with execution data.
For report generation the same class files must be used as at runtime.
Execution data for class com/yourpkg/A does not match.
Execution data for class com/yourpkg/B does not match.