多模块Android项目集成测试代码覆盖率报告生成求助
跨模块Android集成测试覆盖率报告解决方案
针对所有集成测试集中在app模块androidTest目录、需要覆盖其他feature模块和Java工具模块的场景,可通过以下步骤实现全模块覆盖率收集与合并:
1. 为所有被测试模块启用覆盖率收集
默认只有测试代码所在的app模块会生成覆盖率数据,因此需要为其他模块开启覆盖率 instrumentation:
Android功能模块(feature-module1、feature-module2)
在每个模块的build.gradle中添加:
android { buildTypes { debug { testCoverageEnabled true } } }
Java工具模块(util-module)
纯Java库需配置Jacoco支持:
jacoco { toolVersion = "0.8.11" // 使用最新稳定版本 } tasks.withType(Test) { jacoco.includeNoLocationClasses = true }
2. 配置app模块收集跨模块覆盖率数据
修改app模块的build.gradle,指定覆盖率文件输出路径,并添加任务拉取、合并所有模块的覆盖率数据:
android { defaultConfig { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" // 强制将覆盖率数据输出到设备统一路径,方便后续拉取 testInstrumentationRunnerArguments += ["coverageFile": "/sdcard/coverage.ec"] } } // 从设备拉取生成的覆盖率文件到本地 task pullCoverageReport(type: Exec) { dependsOn 'connectedDebugAndroidTest' commandLine 'adb', 'pull', '/sdcard/coverage.ec', "$buildDir/outputs/coverage/merged-coverage.ec" } // 生成合并后的全模块覆盖率报告 task generateMergedCoverageReport(type: JacocoReport) { dependsOn pullCoverageReport group = "Reporting" description = "生成包含所有模块的Jacoco覆盖率报告" // 配置所有模块的class文件路径(排除无需统计的类) def appClasses = fileTree(dir: "$project(':app').buildDir/intermediates/classes/debug", excludes: ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*']) def feature1Classes = fileTree(dir: "$project(':feature-module1').buildDir/intermediates/classes/debug", excludes: ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*']) def feature2Classes = fileTree(dir: "$project(':feature-module2').buildDir/intermediates/classes/debug", excludes: ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*']) def utilClasses = fileTree(dir: "$project(':util-module').buildDir/classes/java/main", excludes: ['**/BuildConfig.*']) // 指定所有模块的源码路径 sourceDirectories.from = files( project(':app').sourceSets.main.java.srcDirs, project(':feature-module1').sourceSets.main.java.srcDirs, project(':feature-module2').sourceSets.main.java.srcDirs, project(':util-module').sourceSets.main.java.srcDirs ) // 指定所有模块的class文件 classDirectories.from = files(appClasses, feature1Classes, feature2Classes, utilClasses) // 指定拉取到的合并覆盖率数据文件 executionData.from = file("$buildDir/outputs/coverage/merged-coverage.ec") // 配置报告输出格式 reports { html.enabled = true // HTML报告(最直观) xml.enabled = true // XML报告(用于CI工具) csv.enabled = false // 可根据需求开启 } }
3. 生成完整覆盖率报告
在终端执行以下命令:
./gradlew generateMergedCoverageReport
该命令会自动完成:运行所有集成测试 → 从设备拉取覆盖率文件 → 合并所有模块的源码与class数据 → 生成完整的覆盖率报告。报告默认输出在app/build/reports/jacoco/generateMergedCoverageReport/html目录下,打开index.html即可查看全模块覆盖率详情。
常见问题排查
- 部分模块覆盖率未统计:检查对应模块是否开启了
testCoverageEnabled(Android模块)或Jacoco配置(Java模块);若为Kotlin模块,class文件路径需改为buildDir/intermediates/classes/kotlin/debug。 - 覆盖率文件拉取失败:手动执行
adb shell ls /sdcard/coverage.ec确认文件存在,若不存在需检查testInstrumentationRunnerArguments配置是否正确,或设备是否有写入权限(可临时关闭设备的存储权限限制)。 - 无覆盖率数据:确保集成测试确实执行了对应模块的代码,未被测试覆盖的代码不会出现在报告中。
内容的提问来源于stack exchange,提问作者Rich Luick
相关产品推荐
相关产品推荐

