Filter JaCoCo coverage reports with Gradle

Problem:

I have a project with jacoco and I want to be able to filter certain classes and/or packages.

Related Documentation:

I have read the following documentation:

Official jacoco site: http://www.eclemma.org/jacoco/index.html

Official jacoco docs for gradle: https://gradle.org/docs/current/userguide/jacoco_plugin.html

Official jacoco Github issues, working on coverage: https://github.com/jacoco/jacoco/wiki/FilteringOptions https://github.com/jacoco/jacoco/issues/14

Related StackOverflow Links:

JaCoCo & Gradle - Filtering Options (No answer)

Exclude packages from Jacoco report using Sonarrunner and Gradle (Not using sonar)

JaCoCo - exclude JSP from report (It seems to work for maven, I am using gradle)

Maven Jacoco Configuration - Exclude classes/packages from report not working (It seems to work for maven, I am using gradle)

JaCoCo gradle plugin exclude (Could not get this to work)

Gradle Jacoco - coverage reports includes classes excluded in configuration (Seems very close, it used doFirst, did not work for me)

Example of what I have tried:

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

buildscript {
    repositories {
        mavenCentral()
        jcenter()
    }
}

repositories {
    jcenter()
}

jacocoTestReport {
    reports {
        xml {
            enabled true // coveralls plugin depends on xml format report
        }

        html {
            enabled true
        }
    }

    test {
        jacoco {
            destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
            classDumpFile = file("$buildDir/jacoco/classpathdumps")
            excludes = ["projecteuler/**"] // <-- does not work
            // excludes = ["projecteuler"]
        }
    }
}

Question:

How can I exclude certain packages and classes when generating the jacoco coverage reports?


Thanks to, Yannick Welsch:

After searching Google, reading the Gradle docs and going through older StackOverflow posts, I found this answer on the Official gradle forums!

jacocoTestReport {
    afterEvaluate {
        classDirectories.setFrom(files(classDirectories.files.collect {
            fileTree(dir: it, exclude: 'com/blah/**')
        }))
    }
}

Source: https://issues.gradle.org/browse/GRADLE-2955

For older gradle versions < 5.x may need to use classDirectories = files(classDirectories.files.collect { instead of classDirectories.setFrom

Solution to my build.gradle for Java/Groovy projects:

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

jacocoTestReport {
    reports {
        xml {
            enabled true // coveralls plugin depends on xml format report
        }

        html {
            enabled true
        }
    }

    afterEvaluate {
        classDirectories = files(classDirectories.files.collect {
            fileTree(dir: it,
                    exclude: ['codeeval/**',
                              'crackingthecode/part3knowledgebased/**',
                              '**/Chapter7ObjectOrientedDesign**',
                              '**/Chapter11Testing**',
                              '**/Chapter12SystemDesignAndMemoryLimits**',
                              'projecteuler/**'])
        })
    }
}

As you can see, I was successfully able to add more to exclude: in order to filter a few packages.

Source: https://github.com/jaredsburrows/CS-Interview-Questions/blob/master/build.gradle

Custom tasks for other projects such as Android:

apply plugin: 'jacoco'

task jacocoReport(type: JacocoReport) {
    reports {
        xml {
            enabled true // coveralls plugin depends on xml format report
        }

        html {
            enabled true
        }
    }

    afterEvaluate {
        classDirectories = files(classDirectories.files.collect {
            fileTree(dir: it,
                    exclude: ['codeeval/**',
                              'crackingthecode/part3knowledgebased/**',
                              '**/Chapter7ObjectOrientedDesign**',
                              '**/Chapter11Testing**',
                              '**/Chapter12SystemDesignAndMemoryLimits**',
                              'projecteuler/**'])
        })
    }
}

Source: https://github.com/jaredsburrows/android-gradle-java-app-template/blob/master/gradle/quality.gradle#L59


For Gradle version 5.x, the classDirectories = files(...) gives a deprecation warning and does not work at all starting from Gradle 6.0 This is the nondeprecated way of excluding classes:

jacocoTestReport {
    afterEvaluate {
        classDirectories.setFrom(files(classDirectories.files.collect {
            fileTree(dir: it, exclude: 'com/exclude/**')
        }))
    }
}