Jacoco 在 Gradle 7.0.2 和 Kotlin 1.5.10 上失败

Jacoco fails on Gradle 7.0.2 and Kotlin 1.5.10

今天我更新了 gradle 和 android studio 中的 kotlin 依赖项。

新版本如下:

kotlin_version = "1.5.10"
...
jacoco {
    toolVersion = "0.8.6"
}
...
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip

测试覆盖率报告任务失败并出现以下错误:

2021-05-27T16:57:49.150+0200 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter] Executing actions for task ':consumerkit:testDebugUnitTestCoverage'.
2021-05-27T16:57:49.304+0200 [DEBUG] [org.codehaus.groovy.vmplugin.VMPluginFactory] Trying to create VM plugin `org.codehaus.groovy.vmplugin.v9.Java9` by checking `java.lang.Module`, but failed:
java.lang.ClassNotFoundException: java.lang.Module
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at org.codehaus.groovy.vmplugin.VMPluginFactory.lambda$createPlugin[=12=](VMPluginFactory.java:61)
        at java.security.AccessController.doPrivileged(Native Method)

对于 Kotlin 1.5,您应该使用 JaCoCo 0.8.7 而不是 0.8.6 - 请参阅 https://github.com/jacoco/jacoco/pull/1164 and the full changelog at https://www.jacoco.org/jacoco/trunk/doc/changes.html

示例片段:

// build.gradle or build.gradle.kts
jacoco {
    toolVersion = "0.8.7"
}

我已经有了

jacoco {
    toolVersion = "0.8.7"
}

已配置,但它仍然无法正常工作,解决问题的方法是遵循此评论 here

  1. 在您的模块中 build.gradle 切换回:
android {
    //....
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }
}

别担心,如果您还没有使用 Java 11 语言功能,它不会破坏任何东西,AGP 7 仍然与 JDK 8 作为目标兼容。

  1. 然后你需要强制AGP使用0.8.7版本而不是默认的0.8.3版本。在根 build.gradle 文件的 allprojects 块中,添加:
allprojects {
  //... other things

  // workaround to fix an auto-import of a lower Jacoco version
  resolutionStrategy {
    eachDependency { details ->
      if ('org.jacoco' == details.requested.group) {
        details.useVersion "0.8.7"
      }
    }
  }
}

现在它应该可以使用:

AGP 7.0.X
Kotlin 1.5.X
JDK 11 (embedded with AS)

简单做

jacoco {
    toolVersion = "0.8.7"
}

对我来说还不够。我还必须覆盖 Android 使用的版本,以便 androidJacocoAnt 依赖项也使用 0.8.7。 (./gradlew app:dependencies) 也只需将此添加到您的 gradle

android.jacoco.version = "0.8.7"

这是一个很老的线程,但是这些解决方案并没有完全解决我在 Android 项目中的问题(实际上是在 Java 中编写的 - 而不是在 Kotlin 中),所以我将在此处添加我的解决方案。也许有人会觉得有用。

除了将 jacoco toolVersion 更新为 0.8.7,我还必须按如下方式更新 jacoco 配置中的执行数据:

project.afterEvaluate {
  tasks.create(name: "${unitTestTask}Coverage", type: JacocoReport, 
  dependsOn: [
    "$unitTestTask",
    ":sdk:testDebugUnitTest",
    ":sdk:connectedCheck"
  ]) {

   /* all jacoco custom configuration goes here... */

    executionData(fileTree(dir: "$buildDir", includes: [
      "jacoco/testDebugUnitTest.exec",        
      "outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec",
      "outputs/code_coverage/debugAndroidTest/connected/*coverage.ec"
    ]))
  }
}

在此配置中,我必须添加以下行:

"outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec"

以前不存在,因为声纳使用的生成报告的文件是在新位置生成的。报告是使用 gradle 任务 testDebugUnitTestCoverage 生成的。毕竟,我能够通过声纳在 java 中生成测试覆盖率报告,包括 connected/instrumentation Android 测试和常规单元测试。