Aggregate several JaCoCo .exec files into a single Coverage report with Gradle

4.7k Views Asked by At

Situation I'm working on a Spring Boot application that is coming along nicely, but the build-test cycle takes too long to be practical in a plain Dev environment.

So, I recently decided to split-up my unit-tests and integration tests. The integration tests are based on Cucumber whereas the unit tests are plain JUnit 5 tests.

For this I used the Gradle plugin org.unbroken-dome.test-sets which nicely creates the relevant sourceSets etc.

testSets {
    intTest { dirName = 'int-test' }
}

Everything is working nicely and my tests are executing as intended. The unit tests are still executed when I do a build and the integration tests are executed when I call `gradlew intTest'. This is by design, as I don't want to execute all tests all the time.

After running the tests, I also have a jacoco/test.exec file and a jacoco/inttest.exec file. All by design and as advertised by the test-sets plugin.

Problem Here's my problem. When I had all my tests still in the test-SourceSet, so before the split and with only the test.exec file generated, JaCoCo reported a coverage of around 75%. But now that I have split up the tests and having the test.exec and intTest.exec files, JaCoCo only reports a coverage of 15%, which is about right considering the extent of my unit tests and integration tests.

Question How can I get JaCoCo to use both the test.exec and the intTest.exec files to report the coverage and allow for the coverage verification task to consider both again?

Relevant Code Here is some of the relevant code: jacoco.gradle

apply plugin: 'java'
apply plugin: 'jacoco'

// -----------------------------------------------------------
//
// JaCoCo
dependencies {
    implementation "org.jacoco:org.jacoco.agent:${jacocoToolVersion}:runtime"
}

jacoco {
    toolVersion = "${jacocoToolVersion}"
}

jacocoTestReport {
    dependsOn test
    reports {
        xml.enabled false
        csv.enabled true
        html.destination file("${buildDir}/reports/jacoco/Html")
        csv.destination file("${buildDir}/reports/jacoco/jacoco.csv")
    }
}

jacocoTestCoverageVerification {
    violationRules {
        rule {
            limit {
                minimum = minCodeCoverage
            }
        }
    }
}

check.dependsOn jacocoTestCoverageVerification

Snippet from build.gradle:

tasks.withType(Test) {
    useJUnitPlatform()
    testLogging {
        events "passed", "skipped", "failed"
    }
    testLogging.showStandardStreams = true
    reports {
        junitXml.enabled = true
        html.enabled = true
    }
}

and

testSets {
    intTest { dirName = 'int-test' }
}

intTest.mustRunAfter test
check.dependsOn intTest

test {
    systemProperties System.getProperties()

    finalizedBy jacocoTestReport
}

Thanks in advance for helping me out or pointing me into the right direction.

1

There are 1 best solutions below

0
On

Okay, you know that once you've articulated your question, you know what to Google? Well after some more digging around I got some inspiratipon that gave me this as a jacocoTestReport definition:

jacocoTestReport {
    dependsOn test
    sourceSets sourceSets.main
    executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec")
    reports {
        xml.enabled false
        csv.enabled true
        html.destination file("${buildDir}/reports/jacoco/Html")
        csv.destination file("${buildDir}/reports/jacoco/jacoco.csv")
    }
}

The mistake I had made was in that I had the exec files aggregated in the jacocoTestCoverageVerification section, instead of the jacocoReport.

So, putting the executionData part in the right place, gave me the correct coverage values again. Yoohoo!!!