首页 > 解决方案 > 当我的所有测试都在单独的子模块中时,如何使用 gradle 插件获取 Jacoco 覆盖率报告

问题描述

由于我是 gradle 新手,因此我无法为我的 java 项目设置 jacoco 覆盖范围。我的最终目标是将其连接到声纳。我所有的测试都在一个单独的模块中

结构体:

./build.gradle
settings.gradle

./submodule1/build.gradle
./submodule1/src/main/java/prismoskills/Foo.java

./submodule2/build.gradle
./submodule2/src/main/java/com/project/prismoskills/Bar.java

./test/build.gradle
./test/src/test/java/prismoskills/TestFooBar.java

我能想到的一种方法是在 test 模块中设置additionalSourceDirs并仅在 root 和 test 模块中启用 jacoco。

这种方法的问题是我的项目有很多子模块(我没有在这里显示)并且我无法以自动化的方式将附加的源目录传递给测试模块的 JacocoReport 任务。

看起来这个用例可以通过参考这个 https://prismoskills.appspot.com/lessons/Maven/Chapter_06_-_Jacoco_report_aggregation.jsp在 maven 中轻松处理

任何有关如何进一步使用 gradle 的线索将不胜感激。提前致谢

gradle version: 6.4
jacoco gradle plugin version: 0.8.5

标签: gradlesonarqubebuild.gradlejacocojacoco-plugin

解决方案


我认为以下解决方案应该可以解决您的问题。这个想法是:

  1. 为每个项目生成 JaCoCo 执行文件
  2. 最后生成一份包含所有数据的 XML 报告

它对 JUnit 报告的作用相同,因为在根项目中一起查看所有测试报告比在目录之间导航更容易。

plugins {
    id 'base'
    id 'org.sonarqube' version '3.0'
}

allprojects {
    apply plugin: 'jacoco'
    apply plugin: 'project-report'

    // ...
    
    jacoco {
        toolVersion = 0.8.5
    }
}

subprojects {
    // ...

    test {
        reports.html.enabled = false
        useJunitPlatform()
        finalizedBy jacocoTestReport
    }

    jacocoTestReport {
        dependsOn test
        reports.html.enabled = false
    }
}

// ...

task testReport(type: TestReport) {
    destinationDir = file("${buildDir}/reports/test")
    reportOn subprojects*.test
}
task jacocoTestReport(type: JacocoReport) {
    subprojects { subproject ->
        subproject.tasks.findAll { it.extensions.findByType(JacocoTaskExtension) }.each { extendedTask ->
            configure {
                sourceSets subproject.sourceSets.main
                if (file("${subproject.buildDir}/jacoco/${extendedTask.name}.exec").exists()) {
                    executionData(extendedTask)
                }
            }
        }
    }
    reports.xml.enabled = true
}
rootProject.getTasksByName('test', true).each {
    it.finalizedBy(testReport)
    it.finalizedBy(jacocoTestReport)
}

这条线

if (file("${subproject.buildDir}/jacoco/${extendedTask.name}.exec").exists()) {

添加以防止在某些子项目根本没有测试时构建失败。


推荐阅读