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

多模块Android Gradle项目生成单个Jacoco代码覆盖率报告方案

多模块Android项目生成统一Jacoco覆盖率报告方案

1. 根项目build.gradle配置

在根项目中统一引入Jacoco及报告聚合相关插件,配置全局Jacoco版本和聚合任务:

plugins {
    id 'com.android.application' version '8.1.0' apply false
    id 'com.android.library' version '8.1.0' apply false
    id 'org.jetbrains.kotlin.android' version '1.8.10' apply false
    id 'jacoco'
    id 'com.android.test.report-aggregation' version '8.1.0'
}

jacoco {
    toolVersion = "0.8.10" // 统一指定Jacoco版本
}

// 全局配置测试任务的Jacoco参数
tasks.withType(Test) {
    jacoco.includeNoLocationClasses = true
    jacoco.excludes = ['jdk.internal.*', 'android.*', 'com.android.*']
}

// 自定义全项目聚合覆盖率报告任务
task aggregateJacocoReport(type: JacocoReport) {
    // 配置报告输出格式和路径
    reports {
        html.required = true
        xml.required = true
        csv.required = false
        html.outputLocation = file("$buildDir/reports/jacoco/aggregate/html")
        xml.outputLocation = file("$buildDir/reports/jacoco/aggregate/jacoco.xml")
    }

    // 收集所有子模块的Jacoco执行数据
    executionData = files(project.rootProject.subprojects.collect { subproject ->
        subproject.tasks.withType(Test).findAll { it.jacoco.enabled }.jacoco.executionData
    })

    // 收集所有子模块的源码文件
    sourceDirectories = files(project.rootProject.subprojects.collect { subproject ->
        subproject.sourceSets.main.java.srcDirs + subproject.sourceSets.main.kotlin.srcDirs
    })

    // 收集所有子模块的编译类文件
    classDirectories = files(project.rootProject.subprojects.collect { subproject ->
        subproject.sourceSets.main.output.classesDirs
    })

    // 排除无需统计的类文件
    classDirectories.setFrom(classDirectories.files.collect { file ->
        fileTree(dir: file, exclude: [
                '**/R.class',
                '**/R$*.class',
                '**/BuildConfig.*',
                '**/Manifest*.*',
                '**/*Test*.*',
                '**/mock/*',
                'android/**',
                'com/android/**'
        ])
    })
}

// 让聚合任务依赖所有子模块的测试任务
aggregateJacocoReport.dependsOn(project.rootProject.subprojects.tasks.withType(Test))

2. 子模块build.gradle配置

所有Android模块(Application/Library)都需要开启Jacoco并配置测试任务:

Application模块示例

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'jacoco'
}

android {
    // 保留原有配置,新增以下内容
    buildTypes {
        debug {
            testCoverageEnabled true // 开启debug构建的覆盖率收集
        }
    }

    testOptions {
        unitTests.all {
            jacoco.enabled = true
            jvmArgs '-noverify' // 避免Android依赖类的Jacoco报错
        }
        animationsDisabled = true
    }
}

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

Library模块示例

仅需替换插件类型,其余配置与Application模块一致:

plugins {
    id 'com.android.library'
    id 'org.jetbrains.kotlin.android'
    id 'jacoco'
}

android {
    buildTypes {
        debug {
            testCoverageEnabled true
        }
    }

    testOptions {
        unitTests.all {
            jacoco.enabled = true
            jvmArgs '-noverify'
        }
        animationsDisabled = true
    }
}

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

3. 生成统一报告

在终端执行以下命令:

./gradlew clean aggregateJacocoReport

执行完成后,全项目统一覆盖率报告的HTML文件会生成在根项目/build/reports/jacoco/aggregate/html目录下,打开index.html即可查看完整的覆盖率统计。

常见问题排查

  • 无执行数据:确认所有子模块的debug构建类型开启了testCoverageEnabled true,且测试任务正常执行。
  • 报告包含无效类:调整classDirectories的exclude规则,按需排除R类、BuildConfig、测试类等无需统计的文件。
  • Kotlin模块适配:确保sourceDirectories包含了Kotlin源码目录,即subproject.sourceSets.main.kotlin.srcDirs。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:50:04