多模块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
相关产品推荐
相关产品推荐

