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

如何为多模块Android项目生成统一JaCoCo代码覆盖率报告

全局JaCoCo覆盖率报告解决方案(含单元测试统计)

核心修改思路

要生成覆盖所有模块的全局报告,需在**项目根目录的build.gradle**中配置跨模块的Jacoco任务,同时修正单元测试执行数据的路径,确保本地单元测试和Instrumented测试的覆盖率都被统计。

步骤1:根目录build.gradle全局配置

替换原有模块内的jacoco.gradle配置,在根目录build.gradle中添加以下代码:

plugins {
    id 'jacoco' apply false
}

subprojects {
    apply plugin: 'jacoco'

    jacoco {
        toolVersion = "0.8.10" // 可根据需求调整JaCoCo版本
    }

    // 确保每个模块生成单元测试执行数据
    tasks.withType(Test) {
        jacoco.includeNoLocationClasses = true
        jacoco.excludeClassLoaders = ['jdk.internal.loader.ClassLoaders$AppClassLoader']
        jacoco.output = JacocoTaskOutput.FILE
    }
}

// 全局覆盖率报告任务
tasks.register('jacocoGlobalTestReport', JacocoReport) {
    group = 'Reporting'
    description = 'Generate global JaCoCo coverage report for all modules'

    // 依赖所有模块的单元测试和Instrumented测试任务
    dependsOn subprojects.testDebugUnitTest, subprojects.createDebugCoverageReport

    reports {
        xml.required.set(true)
        html.required.set(true)
        html.outputLocation = layout.buildDirectory.dir('reports/jacoco/global/html')
        xml.outputLocation = layout.buildDirectory.dir('reports/jacoco/global/xml/report.xml')
    }

    // 收集所有模块的class文件
    classDirectories.from(subprojects.collect { project ->
        project.fileTree(dir: "${project.buildDir}/intermediates/javac/debug", excludes: [
                '**/R.class',
                '**/R$*.class',
                '**/BuildConfig.*',
                '**/Manifest*.*',
                '**/*RealmProxy.*',
                '**/*ColumnInfo.*',
                '**/*RealmModule*.*',
                '**/AutoValue_*.*',
                '**/Dagger*.*',
                '**/*Module_Provide*Factory.*',
                '**/*_Factory.*',
                '**/*_MembersInjector.*',
                '**/*_LifecycleAdapter.*',
                '**/*$ViewInjector*.*',
                '**/*$ViewBinder*.*'
        ])
    })

    // 收集所有模块的源码目录
    sourceDirectories.from(subprojects.collect { project ->
        project.files("${project.projectDir}/src/main/java", "${project.projectDir}/src/debug/java")
    })

    // 收集所有模块的执行数据:单元测试(.exec) + Instrumented测试(.ec)
    executionData.from(subprojects.collect { project ->
        files(
                // 本地单元测试执行数据(新版Gradle路径)
                project.fileTree(dir: "${project.buildDir}/jacoco", include: 'testDebugUnitTest.exec'),
                // Instrumented测试执行数据
                project.fileTree(dir: "${project.buildDir}/outputs/code_coverage/debugAndroidTest/connected", include: '**/*.ec')
        )
    })
}

步骤2:移除模块内的旧配置

删除各模块中单独的jacoco.gradle或相关配置,避免冲突。

关键修正说明

  1. 单元测试路径修正:
    旧配置中单元测试执行数据路径outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec已过时,新版Gradle将单元测试的Jacoco数据存放在build/jacoco/testDebugUnitTest.exec,这是之前未统计单元测试的核心原因。

  2. 跨模块数据收集:
    通过subprojects遍历所有模块,统一收集每个模块的class文件、源码目录和执行数据,最终合并为全局报告。

  3. 兼容性处理:
    在tasks.withType(Test)中添加的jacoco.includeNoLocationClasses和excludeClassLoaders配置,解决了Java 11+和Android测试中的类加载器兼容性问题,避免覆盖率统计遗漏。

运行方式

在终端执行以下命令生成全局报告:

./gradlew jacocoGlobalTestReport

报告生成后,可在项目根目录的build/reports/jacoco/global/html下打开index.html查看可视化报告。

内容的提问来源于stack exchange,提问作者Léon Le Breton

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:03:28