我很难将Jacoco覆盖报告与Gradle多项目结合起来。为简单起见,我创建了一个简化版本,其结构如下。我在GitHub上有示例项目。
+ root
+ common-a
+ common-b
+ project-a
+ project-b
root
,project-a
和project-b
是Spring Boot应用程序。对于某些情况,项目意味着是一种微服务。因此,根项目只是在一个过程中运行所有微服务。
并非所有项目都有单元和/或集成测试。 common-a
子项目没有任何测试; common-b
,project-a
和project-b
项目都有单元和集成测试; root
项目只有集成测试。
子项目的Jacoco覆盖报告是正确的。它能够将单元测试和集成测试结合到一个有凝聚力的报告中。但是,root
项目无法正确生成内聚报告。
我尝试了许多解决方案并取得了成功。我发现的大多数解决方案都假设root
项目只是一个逻辑容器,只有子项目有测试代码。我尝试的解决方案的结果属于以下三个类别之一。
build/reports/jacoco
目录root
项目root
和子项目的完整Jacoco覆盖率报告,但覆盖范围为0%;它应该是100%的覆盖率以下是当前的build.gradle
文件。
buildscript {
repositories {
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.5.RELEASE")
}
}
// settings for all projects
allprojects {
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'jacoco'
group 'io.github.chriszhong'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
repositories {
jcenter()
}
dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:2.0.5.RELEASE'
}
}
sourceSets {
integrationTest {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
java {
srcDir 'src/test-integration/java'
}
resources {
srcDir 'src/test-integration/resources'
}
}
}
configurations {
integrationTestCompile {
extendsFrom testCompile
}
integrationTestRuntime {
extendsFrom testRuntime
}
}
idea {
module {
testSourceDirs += sourceSets.integrationTest.java.srcDirs
testSourceDirs += sourceSets.integrationTest.resources.srcDirs
}
}
task integrationTest(type: Test) {
check {
dependsOn integrationTest
}
testClassesDir sourceSets.integrationTest.output.classesDir
classpath = sourceSets.integrationTest.runtimeClasspath
}
task testReport(type: TestReport) {
dependsOn check
destinationDir file("${reporting.baseDir}/unified/html")
reportOn test, integrationTest
}
task jacocoMerge(type: JacocoMerge) {
dependsOn check
executionData test, integrationTest
// temporary hack to fix a bug requiring that there be at least one test case in each source set for coverage data to be generated;
// it should be if there is at least one test case in any of the source sets
executionData = files(executionData.findAll({ it.exists() }))
}
tasks.withType(Test) {
reports {
html {
destination file("${reporting.baseDir}/${task.name}/html")
}
}
}
tasks.withType(JacocoReport) {
dependsOn jacocoMerge
executionData jacocoMerge.destinationFile
// temporary hack to fix a bug requiring that there be at least one test case in each source set for coverage data to be generated;
// it should be if there is at least one test case in any of the source sets
// executionData = files(executionData.findAll({ it.exists() }))
}
}
apply plugin: 'spring-boot'
version '1.0-SNAPSHOT'
dependencies {
compile project(':project-a')
compile project(':project-b')
testCompile 'junit:junit'
integrationTestCompile 'org.springframework.boot:spring-boot-starter-test'
}
testReport {
dependsOn check, subprojects.testReport
reportOn test, integrationTest, subprojects.test, subprojects.integrationTest
}
jacocoMerge {
dependsOn check, subprojects.jacocoMerge
executionData test, integrationTest, subprojects.jacocoMerge.destinationFile
// temporary hack to fix a bug requiring that there be at least one test case in each source set for coverage data to be generated;
// it should be if there is at least one test case in any of the source sets
executionData = files(executionData.findAll({ it.exists() }))
}
//jacocoTestReport {
// dependsOn jacocoMerge
// executionData test, integrationTest, subprojects.test, subprojects.integrationTest
// executionData jacocoMerge.destinationFile
// temporary hack to fix a bug requiring that there be at least one test case in each source set for coverage data to be generated;
// it should be if there is at least one test case in any of the source sets
// executionData = files(executionData.findAll({ it.exists() }))
// sourceDirectories = files(sourceSets.main.java.srcDirs, subprojects.sourceSets.main.java.srcDirs)
// classDirectories = files(sourceSets.main.output.classesDir, subprojects.sourceSets.main.output.classesDir)
//}
task wrapper(type: Wrapper) {
gradleVersion '2.14'
distributionUrl "https://services.gradle.org/distributions/gradle-${gradleVersion}-all.zip"
}
过去一周,我一直在为这个问题磕头,并且在我的智慧结束时。我非常感谢能解决这个问题的任何帮助。