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

如何用Android Gradle插件生成单元测试JaCoCo XML覆盖率报告?

解决方案:Android单元测试JaCoCo XML覆盖率报告配置(多产品风味)

一、优先使用AGP内置支持(避免触发仪器化测试)

AGP 7.0+已经将单元测试和仪器化测试的覆盖率配置拆分,只要正确使用enableUnitTestCoverage,就不会触发connectedAndroidTest:

  1. 修改app/build.gradle(Groovy)中的buildType配置:
android {
    buildTypes {
        debug {
            // 仅开启单元测试覆盖率,不会触发仪器化测试任务
            enableUnitTestCoverage true
        }
    }

    // 保留你的5个产品风味配置
    productFlavors {
        flavor1 {}
        flavor2 {}
        flavor3 {}
        flavor4 {}
        flavor5 {}
    }
}
  1. 生成单个风味的XML报告
    AGP会自动为每个风味+debug构建类型生成专属的单元测试覆盖率任务,比如:
./gradlew createFlavor1DebugUnitTestCoverageReport

执行后,XML报告默认生成在:app/build/reports/coverage/flavor1DebugUnitTest/coverage.xml

  1. 一次性生成所有风味的报告
    添加自定义任务批量执行所有风味的覆盖率任务:
task createAllUnitTestCoverageReports {
    dependsOn android.productFlavors.collect { flavor ->
        "create${flavor.name.capitalize()}DebugUnitTestCoverageReport"
    }
}

运行命令:

./gradlew createAllUnitTestCoverageReports

二、手动配置JaCoCo(更灵活的场景)

如果需要自定义排除规则、报告路径等,可手动配置,但必须关闭AGP内置支持避免冲突:

  1. 关闭AGP内置覆盖率并引入JaCoCo插件
android {
    buildTypes {
        debug {
            // 关闭AGP内置支持,防止冲突
            enableUnitTestCoverage false
        }
    }
}

plugins {
    id 'jacoco'
}

jacoco {
    // 使用与AGP兼容的版本(AGP 8.x推荐0.8.10+)
    toolVersion = "0.8.10"
}
  1. 为每个风味创建自定义JaCoCo报告任务
android.productFlavors.each { flavor ->
    def buildType = 'debug'
    def variantName = "${flavor.name}${buildType.capitalize()}"
    def testTaskName = "test${variantName}UnitTest"

    task "jacoco${variantName}UnitTestReport"(type: JacocoReport) {
        dependsOn testTaskName

        // 排除无需统计的类
        classDirectories.setFrom(fileTree(dir: "${project.buildDir}/intermediates/javac/${variantName}/classes",
                excludes: [
                        '**/R.class',
                        '**/R$*.class',
                        '**/BuildConfig.*',
                        '**/Manifest*.*',
                        '**/*Test*.*'
                ]))

        // 指定单元测试生成的.exec文件路径
        executionData.setFrom(file("${project.buildDir}/outputs/unit_test_code_coverage/${variantName}/unitTest/${testTaskName}.exec"))

        // 指定源代码路径(包含主代码和风味专属代码)
        sourceDirectories.setFrom(fileTree(dir: "src/main/java") + fileTree(dir: "src/main/kotlin"))
        additionalSourceDirs.setFrom(fileTree(dir: "src/${flavor.name}/java") + fileTree(dir: "src/${flavor.name}/kotlin"))

        // 输出XML格式报告
        reports {
            xml.required.set(true)
            xml.outputLocation.set(file("${project.buildDir}/reports/jacoco/${variantName}UnitTest/coverage.xml"))
            html.required.set(false) // 不需要HTML可关闭
        }
    }
}

// 批量生成所有风味报告的任务
task createAllJaCoCoUnitTestReports {
    dependsOn android.productFlavors.collect { flavor ->
        "jacoco${flavor.name.capitalize()}DebugUnitTestReport"
    }
}

三、避免配置冲突的关键

  • 二选一原则:不要同时开启AGP的enableUnitTestCoverage和手动配置JaCoCo,必须关闭其中一个。
  • 版本兼容:手动配置时,确保JaCoCo工具版本与当前AGP版本匹配(可查看AGP官方文档确认兼容版本)。
  • 路径动态化:避免硬编码文件路径,使用project.buildDir等Gradle内置变量动态获取,适配不同AGP版本的路径变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 13:18:02