升级到AGP 4.2.0后无法生成Jacoco代码覆盖率报告问题求助
核心原因
Android Gradle Plugin(AGP)4.2.0版本重构了代码覆盖率的采集逻辑,修改了子模块构建产物、覆盖率数据文件的默认输出路径,且默认仅会为application类型的app模块自动初始化完整的Jacoco配置,library类型的子模块需要额外显式配置才能正常生成覆盖率数据。
解决方案
- 第一步:所有需要统计覆盖率的library子模块显式开启覆盖率开关
在每个子模块的build.gradle中添加如下配置:
android { buildTypes { debug { // 显式开启当前子模块的覆盖率采集能力 testCoverageEnabled true } } }
- 第二步:修正Jacoco报告任务的路径匹配规则,适配AGP4.2+的新产物路径
在项目根目录的build.gradle或者app模块的build.gradle中自定义全量Jacoco报告任务,适配AGP4.2+的新路径规则:
// 自定义全模块Jacoco覆盖率报告任务 task jacocoFullReport(type: JacocoReport) { def classPaths = files() def sourcePaths = files() def executionData = files() // 遍历收集所有子模块的源码、编译产物、覆盖率数据 subprojects.each { proj -> if (proj.pluginManager.hasPlugin('com.android.library')) { // 收集源码路径 sourcePaths += file("${proj.projectDir}/src/main/java") sourcePaths += file("${proj.projectDir}/src/main/kotlin") // 收集AGP4.2+子模块编译产物路径 classPaths += fileTree(dir: "${proj.buildDir}/intermediates/javac/debug/classes", excludes: getJacocoExcludeFilter()) classPaths += fileTree(dir: "${proj.buildDir}/tmp/kotlin-classes/debug", excludes: getJacocoExcludeFilter()) // 收集子模块instrumented测试覆盖率数据 executionData += fileTree(dir: "${proj.buildDir}/outputs/code_coverage/debugAndroidTest/connected", include: "*.ec") } } // 补充app模块的对应数据 sourcePaths += file("${projectDir}/src/main/java") sourcePaths += file("${projectDir}/src/main/kotlin") classPaths += fileTree(dir: "${buildDir}/intermediates/javac/debug/classes", excludes: getJacocoExcludeFilter()) classPaths += fileTree(dir: "${buildDir}/tmp/kotlin-classes/debug", excludes: getJacocoExcludeFilter()) executionData += fileTree(dir: "${buildDir}/outputs/code_coverage/debugAndroidTest/connected", include: "*.ec") getSourceDirectories().setFrom(sourcePaths) getClassDirectories().setFrom(classPaths) getExecutionData().setFrom(executionData) reports { html.enabled = true xml.enabled = true } } // 通用排除规则,可根据项目自身需求调整 def getJacocoExcludeFilter() { return [ "**/R.class", "**/R\$*.class", "**/BuildConfig.*", "**/Manifest*.*", "**/*_ViewBinding*.*", "**/com/google/**/*.*" ] }
- 第三步:可选,关闭冲突的实验性特性
如果完成上述两步后仍无法正常采集子模块覆盖率数据,在项目的gradle.properties文件中添加如下配置即可:
android.experimental.enableTestCoverageBuildConfigTransform=false
- 第四步:执行命令生成全量覆盖率报告
运行如下命令,会先执行所有模块的instrumented测试生成覆盖率原始数据,再统一生成包含所有模块的覆盖率报告:
./gradlew connectedDebugAndroidTest jacocoFullReport
注意:如果需要统计单元测试的覆盖率,仅需要将上述配置中executionData的路径替换为${proj.buildDir}/jacoco/testDebugUnitTest.exec,并将执行命令替换为./gradlew testDebugUnitTest jacocoFullReport即可。
内容的提问来源于stack exchange,提问作者Dev Soni
相关产品推荐
相关产品推荐

