Jacoco生成测试覆盖率报告报错:app包类文件与执行数据不匹配
解决Jacoco类文件与执行数据不匹配的问题
这个错误的核心原因很明确:你当前的Jacoco配置里,测试执行数据用的是Release变体的,但类文件取的是Debug变体的——两者编译时的参数(比如代码优化、混淆规则)不一样,自然会出现不匹配。下面是具体的修复步骤:
1. 统一构建变体
你的jacocoTestReport任务依赖的是testDebugUnitTest(Debug模式的单元测试),但执行数据却指向了testReleaseUnitTest.exec(Release模式的测试执行数据),这直接导致了不匹配。把执行数据路径改成Debug对应的文件:
// 原来的错误配置 // executionData.from = files("$buildDir/jacoco/testReleaseUnitTest.exec") // 修改后的正确配置 executionData.from = files("$buildDir/jacoco/testDebugUnitTest.exec")
2. 清理旧的执行数据和编译产物
旧的exec文件或者编译后的类文件可能残留,干扰新的报告生成。先执行清理命令:
./gradlew clean
3. 规范类目录配置
你当前的classDirectories.from写法有点冗余,改成更简洁的格式,确保只包含Debug模式下的Kotlin和Java类文件:
classDirectories.from = files(kotlinDebugTree, debugTree)
4. 排查Debug模式下的代码优化(可选)
如果上面的步骤还没解决问题,检查你的项目是否在Debug模式下开启了R8/ProGuard混淆——这会修改类文件结构,导致和测试执行数据不匹配。在app模块的build.gradle里关闭Debug的混淆:
buildTypes { debug { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } }
修复后的完整jacoco.gradle配置
这里把修改后的完整配置贴出来,方便你直接替换:
apply plugin: 'jacoco' ext { coverageExclusions = [ '**/*Activity*.*', '**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/*App.*', '**/*Application.*', '**/*JsonAdapter.*', '**/PilotConnectApplication*.*', '**/Manifest*.*', '**/*Test*.*', '**/com/example/databinding/*', '**/com/example/generated/callback/*', '**/*databinding/*', '**/android/databinding/*', '**/androidx/databinding/*', '**/di/module/*', '**/*MapperImpl*.*', '**/*$ViewInjector*.*', '**/*$ViewBinder*.*', '**/BuildConfig.*', '**/*Component*.*', '**/*BR*.*', '**/Manifest*.*', '**/*$Lambda$*.*', '**/*Companion*.*', '**/*Module.*', '**/*Dagger*.*', '**/*MembersInjector*.*', '**/*_Factory*.*', '**/*_Provide*Factory*.*', '**/*Extensions*.*', '**/*$Result.*', /* filtering `sealed` and `data` classes */ '**/*$Result$*.*' ] } jacoco { toolVersion = '0.8.7' reportsDir = file("$buildDir/reports") } tasks.withType(Test) { jacoco.includeNoLocationClasses = true jacoco.excludes = ['jdk.internal.*'] } tasks.withType(Test) { finalizedBy jacocoTestReport // report is always generated after tests run } task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest']) { group = "Reporting" description = "Generate Jacoco coverage reports for Debug build" reports { xml.required = true html.required = true } def mainSrc = "/src/main/java" def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/debug", excludes: coverageExclusions) def kotlinDebugTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/debug", excludes: coverageExclusions) additionalSourceDirs.from = files(mainSrc) sourceDirectories.from = files([mainSrc]) classDirectories.from = files(kotlinDebugTree, debugTree) // 修复:使用Debug模式的执行数据文件 executionData.from = files("$buildDir/jacoco/testDebugUnitTest.exec") }
最后执行./gradlew jacocoTestReport,应该就能成功生成覆盖率报告了。
内容的提问来源于stack exchange,提问作者Surya Reddy
相关产品推荐
相关产品推荐

