Vampire Vampire - 2 months ago 28
Groovy Question

How do you exclude implicit Groovy closure classes from JaCoCo test resport with Gradle

If you use JaCoCo on a Groovy project, you get a lot of implicitly created closure classes in your coverage report. The source linked to those, are the enclosing classes. The coverage report of the enclosing classes also contains the closure coverage, so it does not add any value to the coverage report. Even worse, it falsifies the coverage report, as the statements to cover in closures are counted twice in the overall statistic.

So how do you exclude those closures from the generated JaCoCo coverage report?

Answer

You can exclude the implicit closure classes from JaCoCo recording with the following snippet, this does not prevent the statements to be recorded in the enclosing class

test {
    jacoco.excludes = ['**/*$*_closure*']
}

With that snippet the coverage is not recorded anymore, but now all closures are shown with 0% coverage in the report and thus also reduce the overall coverage statistic.

Adding the following snippet will remove the closure classes from the JaCoCo report and thus will also give a more meaningful overall statistic. The above snippet is not really necessary, it just brings a little performance improvement as the coverage does not need to be recorded and transformed for the report, so I suggest using both snippets.

jacocoTestReport {
    doFirst {
        classDirectories = classDirectories.collect { fileTree(it) { exclude '**/*$*_closure*' } }.sum()
    }
}

If you have multiple Test and JacocoReport tasks that you want to modify this way, you can of course also do it generically like

tasks.withType(Test) {
    jacoco.excludes = ['**/*$*_closure*']
}

tasks.withType(JacocoReport) {
    doFirst {
        classDirectories = classDirectories.collect { fileTree(it) { exclude '**/*$*_closure*' } }.sum()
    }
}