You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用Jacoco代码覆盖率报告显示0%但测试报告数据正常

Jacoco覆盖率报告0%问题排查与解决

问题背景

此前使用Jacoco生成代码覆盖率报告正常,项目基于JUnit5编写单元测试,依赖de.mannodermaus.android插件支持JUnit5。更新相关依赖后出现异常:

  • 执行Jacoco Gradle任务后,覆盖率报告显示0%
  • 测试结果报告正常,可正确展示测试成功/失败状态

已确认Java与Kotlin类文件路径无误,当前环境:Gradle插件7.2.2、Gradle distribution 7.3.3。

相关配置

应用级Build.gradle

apply from: '../jacoco-config.gradle' 
apply plugin: "de.mannodermaus.android-junit5"

androidTestImplementation "de.mannodermaus.junit5:android-test-core:1.3.0"
androidTestRuntimeOnly "de.mannodermaus.junit5:android-test-runner:1.3.0"
// (Required) Writing and executing Unit Tests on the JUnit Platform
testImplementation "org.junit.jupiter:junit-jupiter-api:5.8.2"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.8.2"

// (Optional) If you need "Parameterized Tests"
testImplementation "org.junit.jupiter:junit-jupiter-params:5.8.2"

// (Optional) If you also have JUnit 4-based tests
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:5.8.2"

testImplementation "junit:junit:4.13.2"

项目级Build.gradle

classpath "org.jacoco:org.jacoco.core:0.8.8"
classpath "de.mannodermaus.gradle.plugins:android-junit5:1.8.2.1"

jacoco-config.gradle核心配置

apply plugin: 'jacoco'

tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
jacoco.excludes = ['jdk.internal.*']}

jacoco {
toolVersion = "0.8.8"
reportsDir = file("$buildDir/JacocoReport")}

android {
buildTypes {
    debug {
        testCoverageEnabled = true
    }
}
testOptions {
    animationsDisabled true
    unitTests {
        includeAndroidResources = true
        returnDefaultValues = true
    }
}
}
project.afterEvaluate {
project.gradle.taskGraph.whenReady {

    testDebugUnitTest {
        ignoreFailures true
    }
}

def androidExclusion = [
        '**/BR.*',
        '**/R.*',
        '**/R$*.*',
        '**/BuildConfig.*',
        '**/Manifest*.*',
        '**/databinding/*.*'
]

// Create coverage task ex: 'jacocoTestReport<Flavor>' depending on
task "jacocoTestReport"(type: JacocoReport, dependsOn: ['testDebugUnitTest']) {
    group = "Reporting"
    description = "Generate Jacoco coverage reports on the testDebugUnitTest build."

    def javaClasses = fileTree(
            dir: "${project.buildDir}/intermediates/javac/debug",
            excludes: androidExclusion)
    def kotlinClasses = fileTree(
            dir: "${project.buildDir}/tmp/kotlin-classes/debug",
            excludes: androidExclusion)
    classDirectories.from = files([ kotlinClasses , javaClasses])
    def coverageSourceDirs = ["src/main/java"]
    getAdditionalSourceDirs().setFrom(files(coverageSourceDirs))
    getSourceDirectories().setFrom(files(coverageSourceDirs))
    getExecutionData().setFrom(fileTree(dir: project.projectDir, includes: ["**/*.exec", "**/*.ec"]))

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

解决步骤

1. 修正Jacoco执行数据路径

Gradle 7.x+中,JUnit5测试的Jacoco执行数据默认生成在build/outputs/unit_test_code_coverage/debugUnitTest或build/jacoco目录下,而非项目根目录。修改jacocoTestReport中的executionData配置:

getExecutionData().setFrom(fileTree(dir: "${project.buildDir}", includes: [
    "outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec",
    "jacoco/testDebugUnitTest.exec"
]))

2. 适配AGP 7.x的类文件路径

Android Gradle Plugin 7.x调整了编译后类文件的存放路径:

  • Java类文件从intermediates/javac/debug改为intermediates/javac/debug/classes
  • Kotlin类文件从tmp/kotlin-classes/debug改为intermediates/kotlin/debug/classes

更新类文件路径配置:

def javaClasses = fileTree(
        dir: "${project.buildDir}/intermediates/javac/debug/classes",
        excludes: androidExclusion)
def kotlinClasses = fileTree(
        dir: "${project.buildDir}/intermediates/kotlin/debug/classes",
        excludes: androidExclusion)

3. 升级Jacoco版本以适配新AGP

当前使用的Jacoco 0.8.8对AGP 7.x的兼容性有限,建议升级到0.8.10:

  • 项目级Build.gradle:
classpath "org.jacoco:org.jacoco.core:0.8.10"
  • jacoco-config.gradle:
jacoco {
    toolVersion = "0.8.10"
}

4. 清理冗余依赖避免冲突

同时引入JUnit4和JUnit5依赖可能导致测试执行逻辑冲突,若项目无JUnit4测试,移除相关依赖:

// 移除这两行
// testImplementation "junit:junit:4.13.2"
// testRuntimeOnly "org.junit.vintage:junit-vintage-engine:5.8.2"

5. 强制启用Jacoco测试数据生成

在tasks.withType(Test)中明确启用Jacoco,确保测试任务生成执行数据:

tasks.withType(Test) {
    jacoco.includeNoLocationClasses = true
    jacoco.excludes = ['jdk.internal.*']
    jacoco.enabled = true // 新增此行
}

完成以上修改后,重新执行jacocoTestReport任务,即可正常生成覆盖率报告。

内容的提问来源于stack exchange,提问作者Orton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 05:37:56