“未知块类型”从Android读取JaCoCo执行数据文件

问题描述 投票:0回答:1

我想要:

  1. 针对仪器测试可靠运行的代码覆盖率
  2. 测试要相互隔离

我是 Android 开发新手,但对其他开发和工具有经验。

因此,我查找了记录的选项并将以下内容添加到我的 build.gradle 中:

android {
    defaultConfig {testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        testInstrumentationRunnerArguments clearPackageData: 'true'
        testInstrumentationRunnerArguments useTestStorageService: 'true'
    }

    buildTypes {
        debug {
            testCoverageEnabled true
        }
    }

我还有一个自定义任务来生成报告:

task coverageReport(type: JacocoReport) {
    sourceDirectories.setFrom(fileTree(
            dir: "$project.buildDir/src/main/java"
    ))
    classDirectories.setFrom(fileTree(
            dir: "$project.buildDir/build/intermediates/javac/debug",
    ))
    executionData fileTree(dir: project.buildDir, includes: [
            "outputs/code_coverage/debugAndroidTest/connected/*/*.ec"
    ])
}

现在,我在运行测试和生成报告时看到,大约 10% 的时间它遇到了看起来像是损坏的 .ec 文件。 (其余时间,报告就好)

> ./gradlew coverageReport
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:coverageReport'.
> Unable to read execution data file app/build/outputs/code_coverage/debugAndroidTest/connected/Nexus_S_API_33(AVD) - 13/com.example.coverage.ExampleInstrumentedTest#useAppContext.ec

深入研究堆栈跟踪:

Caused by: : Unable to read execution data file app/build/outputs/code_coverage/debugAndroidTest/connected/Nexus_S_API_33(AVD) - 13/com.example.coverage.ExampleInstrumentedTest#useAppContext.ec
        at org.jacoco.ant.ReportTask.loadExecutionData(ReportTask.java:518)
...
Caused by: java.io.IOException: Unknown block type 3.
        at org.jacoco.core.data.ExecutionDataReader.readBlock(ExecutionDataReader.java:119)
        at org.jacoco.core.data.ExecutionDataReader.read(ExecutionDataReader.java:93)
        at org.jacoco.core.tools.ExecFileLoader.load(ExecFileLoader.java:60)
        at org.jacoco.ant.ReportTask.loadExecutionData(ReportTask.java:516)

我在其他项目中看到了未知块类型的其他几个数字,但到目前为止,这个最小的示例项目只有 3 个数字。

设备上和设备外的 .ec 文件的 MD5 和相同:

> adb shell md5sum /data/media/0/googletest/internal_use/data/data/com.example.coverage/coverage_data/com.example.coverage.ExampleInstrumentedTest#useAppContext.ec
89c6b7ac8ad27d4d2f19dce0ac47f028  /data/media/0/googletest/internal_use/data/data/com.example.coverage/coverage_data/com.example.coverage.ExampleInstrumentedTest#useAppContext.ec
> md5sum app/build/outputs/code_coverage/debugAndroidTest/connected/Nexus_S_API_33\(AVD\)\ -\ 13/com.example.coverage.ExampleInstrumentedTest#useAppContext.ec 
89c6b7ac8ad27d4d2f19dce0ac47f028  app/build/outputs/code_coverage/debugAndroidTest/connected/Nexus_S_API_33(AVD) - 13/com.example.coverage.ExampleInstrumentedTest#useAppContext.ec

重新运行测试通常可以解决该项目的问题。在一个较大的项目中,每次运行时都有几个测试会像这样失败——每次都有不同的测试,尽管显然有些测试比其他测试要失败。它似乎与测试的运行时间无关。

我尝试了不同版本:

  • 摇篮(7.4、7.5、8.0-rc-1、8.0-rc-2)
  • AGP(7.4、8.1.0-alpha01)
  • Android Studio(鳗鱼、长颈鹿)
  • 模拟器 SDK 版本(27、31、33) 每个人都有同样的失败。

与 Gradle 文件同步和清理/重建没有帮助,我在第一次运行新项目时就看到过这种情况。

我可以看到:

  • Gradle 对 Android 的支持滞后(Android 明确不支持新的 JaCoCo 聚合报告插件)
  • Gradle 在最近的版本中修复了一些与 JaCoCo 类似的问题(例如 https://github.com/gradle/gradle/issues/20532
  • 在其他上下文中,JaCoCo 也出现了类似的问题(例如 JaCoco MVN 未知块类型,这表明 JVM 在测试之间被硬杀)

关闭

clearPackageData
并不能阻止这些故障。

我期望仪器测试的代码覆盖率成为我开发过程中的核心工具。到目前为止,这个错误看起来要么是“我”的问题,要么 Android 开发人员认为让此错误可靠地工作并没有多大价值。任何关于为什么它没有那么有价值或可以轻松替换的见解都会像修复一样受到欢迎。

android android-gradle-plugin code-coverage jacoco
1个回答
0
投票

我遇到了同样的问题,然后发现了这个 Google bug,随后又发现了 Google 的这个 GitHub 示例


我用适合我的设置回答了这个问题(需要对 GitHub 示例库进行一些小调整):https://stackoverflow.com/a/78111536/2503185

© www.soinside.com 2019 - 2024. All rights reserved.