I wanted:
- Code coverage to run reliably against the instrumented tests
 - Tests to be isolated from each other
 
I'm new to Android development, but experienced with other development and tooling.
So I looked for the documented options and added the following to my build.gradle:
android {
    defaultConfig {testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        testInstrumentationRunnerArguments clearPackageData: 'true'
        testInstrumentationRunnerArguments useTestStorageService: 'true'
    }
    buildTypes {
        debug {
            testCoverageEnabled true
        }
    }
I also have a custom task to generate the report:
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"
    ])
}
Now what I see when running the tests and generating the report, is that about 10% of the time it hits what looks like a corrupted .ec file. (the rest of the time, the report is fine)
> ./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
Digging into the stack trace:
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)
I've seen several other numbers in other projects for the unknown block type, but so far only 3 for this minimal example project.
MD5 sums are the same for the .ec files on and off the device:
> 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
Re-running the tests will generally clear the issue on this project. On a larger project, several tests fail like this on each run - different tests each time, though apparently some more than others. It doesn't appear to be linked to the running time of the test.
I tried different versions of:
- Gradle (7.4, 7.5, 8.0-rc-1, 8.0-rc-2)
 - AGP (7.4, 8.1.0-alpha01)
 - Android Studio (Eel, Giraffe)
 - emulator SDK version (27, 31, 33) with the same failing on each.
 
Syncing with Gradle files and cleaning/rebuilding don't help, and I've seen this happen on the first run of a new project.
I can see that:
- Gradle support for Android lags (the new JaCoCo aggregate report plugin is explicitly not supported on Android)
 - Gradle's had and fixed some similar issues with JaCoCo in recent releases (e.g. https://github.com/gradle/gradle/issues/20532)
 - a similar issue's been seen with JaCoCo in other contexts (e.g. JaCoco MVN unknown block type which suggests the JVM's being hard-killed between tests)
 
Turning off clearPackageData doesn't stop these failures.
I was expecting code coverage of instrumented tests to be a core tool in my development process. So far it looks like either this error is a "me" problem, or Android devs don't see much value in having this working reliably. Any insights into why it's not that valuable or can be easily replaced would be as welcome as a fix.