多模块Gradle项目Jacoco跨模块集成测试覆盖率合并方案咨询
解决多模块Jacoco覆盖率合并问题(Gradle 5.4.1)
针对你的项目结构和现有Gradle配置,要生成包含Dao、Service、Controller所有模块的合并覆盖率报告,你需要在父项目中添加合并Jacoco执行数据的任务,具体操作如下:
1. 修改父项目的build.gradle.kts
在现有配置的末尾(subprojects块之后)添加以下代码,用来收集所有子模块的测试执行数据并生成合并报告:
// 注册任务:合并所有子模块的Jacoco执行数据 val jacocoMerge by tasks.registering(JacocoMerge::class) { // 收集每个子模块test任务生成的.exec文件 executionData(subprojects.flatMap { project -> project.tasks.withType<Test>().map { it.executionData } }) // 合并后的数据文件存到根项目build目录下 destinationFile.set(file("$buildDir/jacoco/allModules.exec")) } // 注册任务:基于合并的数据生成统一覆盖率报告 val jacocoRootReport by tasks.registering(JacocoReport::class) { // 必须等合并任务完成后再执行 dependsOn(jacocoMerge) // 使用合并后的执行数据文件 executionData(jacocoMerge.get().destinationFile) // 收集所有子模块的源码和编译类文件 sourceDirectories.setFrom(subprojects.map { it.java.sourceSets["main"].allSource.srcDirs }) classDirectories.setFrom(subprojects.map { it.java.sourceSets["main"].output.classesDirs }) // 配置报告输出(和子模块保持一致的格式) reports { html.isEnabled = true html.destination = file("$buildDir/reports/jacoco/allModules/html") xml.isEnabled = true xml.destination = file("$buildDir/reports/jacoco/allModules/jacoco.xml") csv.isEnabled = false } // 排除不需要统计的类(和子模块的规则对齐) afterEvaluate { classDirectories.setFrom(files(classDirectories.files.map { fileTree(it).apply { exclude("io/company/common/aws/test/support/**") exclude("io/company/common/system/**") } })) } } // 让根项目的jacocoTestReport依赖合并报告任务,保持原有命令习惯 tasks.jacocoTestReport { dependsOn(jacocoRootReport) }
2. 确认子模块测试任务可执行
虽然你提到仅Controller有集成测试,但要统计Service和Dao的覆盖率,得确保这两个模块的test任务能正常运行——哪怕没有测试类,代码也会被纳入报告(只是覆盖率为0)。如果这两个模块有单元测试,记得写好对应的测试用例来提升覆盖率。
3. 执行命令生成合并报告
现在运行你原来的命令就行:
./gradlew clean test jacocoTestReport
执行完成后,打开根项目下的build/reports/jacoco/allModules/html/index.html,就能看到所有模块的整体覆盖率数据了。
为什么之前的配置不行?
你的现有配置只是给每个子模块单独配置了Jacoco,但Gradle默认不会自动把多模块的覆盖率数据合并起来。我们添加的这两个任务,一个负责收集所有子模块的.exec测试执行文件,另一个基于合并后的数据生成统一报告,这样就能把Dao、Service、Controller的覆盖率都整合到一起了。而且这套配置完全兼容你的Gradle 5.4.1版本,不需要升级Gradle。
内容的提问来源于stack exchange,提问作者AkshatP
相关产品推荐
相关产品推荐

