jacoco 代码覆盖率报告生成器显示错误:“包‘代码覆盖率报告’中的类与执行数据不匹配”

新手上路,请多包涵

我正在使用 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 生成。那为什么会出现这样的错误。任何想法?

原文由 Nishant Lakhara 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.2k
1 个回答

您收到与 classID 相关的错误。这是 JaCoCo 文档站点上详细描述的概念。 http://www.eclemma.org/jacoco/trunk/doc/classids.html 。这是在同一 JVM 中支持类的多个版本(例如应用程序服务器)的关键步骤。

为了可见性,在这里复制它的一部分。

什么是类 ID,它们是如何创建的?

类 ID 是 64 位整数值,例如十六进制表示法中的 0x638e104737889183。他们的计算被认为是 JaCoCo 的一个实现细节。目前,ids 是使用原始类文件的 CRC64 校验和创建的。

什么会导致不同的类 ID?

仅对于完全相同的类文件(逐字节),类 ID 是相同的。有几个原因可能导致您获得不同的类文件。如果使用不同的工具链,首先编译 Java 源文件将产生不同的类文件:

  • 不同的编译器供应商(例如 Eclipse 与 Oracle JDK)

  • 不同的编译器版本

  • 不同的编译器设置(例如调试与非调试)

此外,后处理类文件(混淆、AspectJ 等)通常会更改类文件。如果您只是将相同的类文件用于运行时和分析,JaCoCo 将工作得很好。所以创建这些类文件的工具链并不重要。

即使文件系统上的类文件相同,JaCoCo 运行时代理看到的类也有可能是不同的。当在 JaCoCo 代理或特殊类加载器预处理类文件之前配置另一个 Java 代理时,通常会发生这种情况。典型的候选人是:

  • 模拟框架
  • 应用服务器
  • 持久性框架

同一页涵盖了可能的解决方案。

存在哪些解决方法来处理运行时修改的类?

如果在您的设置中类在运行时被修改,则有一些解决方法可以使 JaCoCo 正常工作:

  • 如果您使用另一个 Java 代理,请确保首先在命令行中指定 JaCoCo 代理。这样 JaCoCo 代理应该可以看到原始类文件。
  • 指定 JaCoCo 代理的 classdumpdir 选项并在报告生成时使用转储的类。请注意,只有已加载的类才会被转储,即根本未执行的类将不会在您的报告中显示为未涵盖。
  • 在运行测试之前使用离线检测。这样,在任何运行时修改发生之前,JaCoCo 就可以对类进行检测。请注意,在这种情况下,必须使用原始类而不是经过检测的类生成报告。

编辑于 22-02-2017

如何使用离线检测: 使用 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" 命令生成报告。

原文由 Jayan 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题