10

I have a build.gradle file which can successfully run unit and integration tests separately or together (with a command like gradle test integrationTest for together). Both use Junit, I'm using Gradle 3, and this isn't an Android project. A report about the success is produced for each, in separate directories. I can also successfully generate a Jacoco report for unit test coverage with gradle test jacoco. I am unable to get a coverage report for my otherwise-working integration tests by using gradle integrationTest jacoco, though the test does successfully run and a integrationTest.exec file is generated.

To be more explicit, I get the unit test coverage report in build/reports/index.html, and the Junit reports in build/reports/test/index.html and build/reports/integrationTest/index.html. A build/reports/jacoco directory is created but contains only an empty "test" directory. build/ also contains a jacoco/ directory, which contains both .exec files and classpathdumps.

Here is my abbreviated build.gradle

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

repositories {
    mavenCentral()
}

sourceSets {
    main {
        java {
            srcDirs = ['src/java']
        }
        test {
            java {
                srcDirs = ['test/java']
            }
        }
        resources {
            srcDirs = ['src/java', 'conf', 'resource']
        }
    }

    integrationTest {
        java {
            compileClasspath += main.output + test.output
            runtimeClasspath += main.output + test.output
            srcDir file('integration_test/java')
        }
    }
}

test {
    jacoco {
        append = false
        destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
        classDumpFile = file("$buildDir/jacoco/classpathdumps")
    }
}

configurations {
    integrationTestCompile.extendsFrom testCompile
    integrationTestRuntime.extendsFrom testRuntime
}

/* SNIP */

task integrationTest(type: Test) {
    dependsOn startserver

    testClassesDir = sourceSets.integrationTest.output.classesDir
    classpath = sourceSets.integrationTest.runtimeClasspath
}
integrationTest.finalizedBy stopserver

check.dependsOn integrationTest
integrationTest.mustRunAfter test

tasks.withType(Test) {
    reports.html.destination = file("${reporting.baseDir}/${name}")
}

jacoco {
    toolVersion = "0.7.6.201602180812"
}

jacocoTestReport {
    reports {
        xml.enabled false
        csv.enabled false
        html.destination "$buildDir/reports"
    }
}

I've seen existing questions about merging two reports, generating the Junit integration test reports I already have, and similar but ultimately unhelpful questions about Maven and Ant. The closest thing I found was this, but nothing I've tried adapting from it has been fruitful. There does seem to be a similar question, but with less of their build.gradle, and the only reply is a 0-up-vote, not-accepted response by the author of the question in the previous link.

Since this is already pretty long, I didn't want to over-provide even more than is here but I'm happy to provide more if anything is unclear.

I've verified that nothing as silly as unit test results overwriting integration tests is happening - running integration tests and jacoco without regular tests doesn't even produce analogous files.

Is there anything I can do to get integration test coverage?

[First edit] I've created a small Github repo that has everything needed to reproduce this problem: https://github.com/micseydel-tile/gradle-jacoco-integration-test

2 Answers 2

2

I finally could get aggregated report by the following approach: Root build.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
}

Run gradle codeCoverageReport

1

You can make both the test tasks write to the same destination file and they append to the existing file if any. This way you can run either of the test tasks and see the coverage individually in the HTML report. This code snippet is from your small github repo

`task integrationTest(type: Test) {jacoco {
    append = true
    destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
    classDumpFile = file("$buildDir/jacoco/classpathdumps")
}
 testClassesDir = sourceSets.integrationTest.output.classesDir
classpath = sourceSets.integrationTest.runtimeClasspath}`

you can simply add the jacoco code block and turn on append.

Not the answer you're looking for? Browse other questions tagged or ask your own question.