首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Kotlin JaCoCo - IllegalClassFormatException.请提供原始的非仪器类。

Kotlin JaCoCo - IllegalClassFormatException.请提供原始的非仪器类。
EN

Stack Overflow用户
提问于 2021-04-28 11:13:54
回答 1查看 6.4K关注 0票数 9

我正在尝试获取我们的Android应用程序模块的测试覆盖率报告,并执行testVariantBuildTypeUnitTest任务。

尽管所有测试都已通过,但TEST-classNameTest.xml文件在下面包含错误消息。此错误仅用于包含来自Kotlin的调用的方法。这个问题有什么解决办法吗?

代码语言:javascript
运行
复制
**Caused by: java.lang.IllegalStateException: Cannot process instrumented class... Please supply original non-instrumented classes.
at org.jacoco.agent.rt.internal_f3994fa.core.internal.instr.InstrSupport.assertNotInstrumented(InstrSupport.java:238)
at org.jacoco.agent.rt.internal_f3994fa.core.internal.instr.ClassInstrumenter.visitField(ClassInstrumenter.java:56)
at org.jacoco.agent.rt.internal_f3994fa.asm.ClassVisitor.visitField(ClassVisitor.java:339)
at org.jacoco.agent.rt.internal_f3994fa.asm.ClassReader.readField(ClassReader.java:1111)
at org.jacoco.agent.rt.internal_f3994fa.asm.ClassReader.accept(ClassReader.java:713)
at org.jacoco.agent.rt.internal_f3994fa.asm.ClassReader.accept(ClassReader.java:401)
at org.jacoco.agent.rt.internal_f3994fa.core.instr.Instrumenter.instrument(Instrumenter.java:90)
at org.jacoco.agent.rt.internal_f3994fa.core.instr.Instrumenter.instrument(Instrumenter.java:108)

我们有多模块android项目,因此我们使用这个定制的Jacoco任务来获得覆盖报告:

代码语言:javascript
运行
复制
project.afterEvaluate {

    (android.hasProperty('applicationVariants')
            ? android.'applicationVariants'
            : android.'libraryVariants')
            .all { variant ->
                def variantName = variant.name
                def unitTestTask = "test${variantName.capitalize()}UnitTest"

                def jacocoReportName = unitTestTask + project.name

                tasks.create(name: jacocoReportName, type: JacocoReport, dependsOn: [
                        "$unitTestTask"
                ]) {
                    group = "Reporting"
                    description = "Generate Jacoco coverage reports for the ${variantName.capitalize()} build"

                    reports {
                        html.enabled = true
                        xml.enabled = true
                    }

                    def fileFilter = [
                            // data binding
                            'android/databinding/**/*.class',
                            '**/android/databinding/*Binding.class',
                            '**/android/databinding/*',
                            '**/androidx/databinding/*',
                            '**/databinding',
                            '**/BR.*',
                            // android
                            '**/R.class',
                            '**/R$*.class',
                            '**/BuildConfig.*',
                            '**/Manifest*.*',
                            '**/*Test*.*'
                    ]

                    def javaClasses = fileTree(dir: variant.javaCompileProvider.get().destinationDir,
                            excludes: fileFilter)
                    def kotlinClasses = fileTree(dir: "${buildDir}/tmp/kotlin-classes/${variantName}",
                            excludes: fileFilter)

                    classDirectories.setFrom(files([
                            javaClasses,
                            kotlinClasses
                    ]))

                    def variantSourceSets = variant.sourceSets.java.srcDirs.collect { it.path }.flatten()
                    sourceDirectories.setFrom(project.files(variantSourceSets))

                    if (isAndroidLibrary(project)) {
                        executionData(files([
                                "${projectDir}/jacoco.exec"
                        ]))
                    }else{
                        executionData(files([
                                "$project.buildDir/jacoco/${project.name}.exec"
                        ]))
                    }

                }

            }
}

致以敬意,

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-22 07:56:44

溶液

问题很可能在于模块级别的build.gradle文件。您需要删除testCoverageEnabled或将其设置为false。

代码语言:javascript
运行
复制
android {
 ...
  buildTypes {
     release {
        minifyEnabled true
     }
     debug {
        // testCoverageEnabled true 
        minifyEnabled false
     }
  }

解释和参考文献

  • 首先,多年来,我一直在JaCoCo上为android上的单元测试覆盖率而苦苦挣扎,并多次遇到这些问题,因为AGP (Android插件)团队增强了AGP (例如类似问题),因此这个解决方案可能会在未来的AGP版本中发生变化。
  • 发布 of AGP 4.1,AGP团队改变了插件处理单元测试的方式。我向AGP团队提出了一个在这里输入链接描述问题,他们解释说,插件(AGP 4.1+)使用它自己的工具来获得覆盖范围,这无疑与JaCoCo不兼容。正是在这个问题上,向我强调了解决办法。

注1:这个问题是无文件文档中的DSL!

注2:还应该注意到,当我编写此AGP 7时,AGP 7正在开发中,同样的问题也会发生。

Considerations

此解决方案将导致生成仪器化测试覆盖范围的问题,因为AGP生成仪器化测试的覆盖率(以.ec文件的形式),这意味着要获得检测测试覆盖率,您必须拥有 testCoverageEnabled true。作为一种解决办法,你可以:

  • 将单元测试放入版本构建变体中。
  • 将您的检测测试放到调试版本变体中。仍然可以将覆盖范围合并到一个报告中:例如:
代码语言:javascript
运行
复制
task jacocoCombinedUnitTestAndroidTestReport(type: JacocoReport) {
        group = "Reporting"

        reports {
            xml.enabled = true
            html.enabled = true
        }

        def mainSrc = "$project.projectDir/src/main/java"
        def releaseKotlinClasses = fileTree(dir: "${buildDir}/tmp/kotlin-classes/release", excludes:["com/example/ui**"])
        def debugKotlinClasses = fileTree(dir: "${buildDir}/tmp/kotlin-classes/debug/com/example/ui/")
        def releaseJavaClasses = fileTree(dir: "${buildDir}/intermediates/javac/release", excludes: ["com/example/ui**"])
        def debugJavaClasses = fileTree(dir: "${buildDir}/intermediates/javac/debug/com/example/ui/" )

        def mainClasses = releaseKotlinClasses + debugKotlinClasses
        def javaClasses = releaseJavaClasses + debugJavaClasses

        sourceDirectories.from = files([mainSrc])
        classDirectories.from = files([mainClasses, javaClasses])
        executionData.from = fileTree(dir: buildDir, include: ["jacoco/testReleaseUnitTest.exec",
                                                                    "outputs/code_coverage/debugAndroidTest/connected/**.ec"])
}
  • 这假设您在UI目录中有任何ui代码。
  • 包含不包括ui目录的所有发行版类。
  • 您只包括ui调试类。

请注意,这是唯一有效的时候,这个答案是写的,并希望谷歌将在未来解决问题。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67299155

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档