我们使用 gradle 3.3 和 jacoco 工具版本 0.7.6.201602180812。 我们有一个像这样的 gradle 多项目:
我们使用单元测试来测试项目源,并在所有生成 test.exec 文件的子项目上使用 jacoco。我们在 int-test 项目中进行了额外的集成测试,将 jacoco 结果添加到 int-test 项目中的 test-exec 中。我们在父项目上使用 sonarqube gradle 插件 (2.2.1) 来收集 SonarQube 服务器 v6.2 的所有内容。
在自己的项目中测试源代码的测试一切都运行良好:代码覆盖率在 jacoco 报告以及 SonarQube 上进行测量。 只有产品项目(单个进程)中源的集成测试(int-test 项目)覆盖率既不会在包含测试的项目的覆盖率报告中进行测量,也不会在包含类的项目中进行测量。 可能需要以某种方式合并顶级项目的覆盖数据 - 有人知道如何做到这一点吗?最好的情况是 SonarQube 仍然显示单个模块级别的覆盖范围。编辑
这是一个小测试项目:https://github.com/MichaelZett/coveragetest
运行
'build SmokeTest sonarqube' 会导致:
如评论中所述,您必须首先合并 Jacoco 执行数据,然后告诉 sonarqube 使用该数据,而不是每个子模块生成的单独
exec
文件。
我在这里添加一个示例,因为接受的答案中提供的链接有点误导。它们中的大多数为您提供了不同的解决方法来合并 Jacoco 报告,而不是合并执行数据,这正是您想要的。
它的样子是这样的:
def allTestCoverageFile = "$buildDir/jacoco/allTestCoverage.exec"
sonarqube {
properties {
property "sonar.projectKey", "your.org:YourProject"
property "sonar.projectName", "YourProject"
property "sonar.jacoco.reportPaths", allTestCoverageFile
}
}
task jacocoMergeTest(type: JacocoMerge) {
destinationFile = file(allTestCoverageFile)
executionData = project.fileTree(dir: '.', include:'**/build/jacoco/test.exec')
}
task jacocoMerge(dependsOn: ['jacocoMergeTest']) {
// used to run the other merge tasks
}
subprojects {
sonarqube {
properties {
property "sonar.jacoco.reportPaths", allTestCoverageFile
}
}
}
简而言之:
allTestCoverageFile
)。sonar.jacoco.reportPaths
)。但请注意,我们还必须在子项目关闭中执行此操作。这一点非常重要。不要错过哦。JacocoMerge
(Jacoco 插件的孵化类)扩展的自定义任务,它将所有项目 (executionData
) 的所有测试覆盖率报告合并到我们的 allTestCoverageFile
中。如果您使用 6.2 之前的 SonarQube 版本,请使用 sonar.jacoco.reportPath 属性
谈到 SonarQube:您可以通过在所有模块中使用
jacoco.exec
的相同位置来获取聚合报告。确保在构建之前删除该文件并将其附加到所有模块中。
仅谈论 Gradle:看看
subprojects {
apply(plugin: 'org.jetbrains.kotlin.jvm')
repositories {
jcenter()
mavenCentral()
}
}
task codeCoverageReport(type: JacocoReport) {
// Gather execution data from all subprojects
executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec")
// Add all relevant sourcesets from the subprojects
subprojects.each {
sourceSets it.sourceSets.main
}
reports {
xml.enabled true
html.enabled true
csv.enabled false
}
}
// always run the tests before generating the report
codeCoverageReport.dependsOn {
subprojects*.test
}
sonarqube {
properties {
property "sonar.projectKey", "your_project_key"
property "sonar.verbose", true
property "sonar.projectName", "Your project name"
property "sonar.coverage.jacoco.xmlReportPaths", "${rootDir}/build/reports/jacoco/codeCoverageReport/codeCoverageReport.xml"
}
}
运行覆盖率测试的命令:
./gradlew codeCoverageReport
./gradlew sonarqube -x test (test is excluded since already run and sonarqube by default executes test)
要使其发挥作用,需要注意两件事: