Filter JaCoCo coverage reports with Gradle

122,814

Solution 1

Thanks to, Yannick Welsch:

After searching Google, reading the Gradle docs and going through older StackOverflow posts, I found this answer on the Official 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

Solution 2

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/**')
        }))
    }
}

Solution 3

for me, it's fine working with

test {
  jacoco {
    excludes += ['codeeval/**',
                 'crackingthecode/part3knowledgebased/**',
                 '**/Chapter7ObjectOrientedDesign**',
                 '**/Chapter11Testing**',
                 '**/Chapter12SystemDesignAndMemoryLimits**',
                 'projecteuler/**']
  }
}

as stated out in documentation https://docs.gradle.org/current/userguide/jacoco_plugin.html#N16E62 and initally asked so the answer is:

so if you ask me: it's not a question of

excludes = ["projecteuler/**"]

or

excludes += ["projecteuler/**"]

but

excludes = ["**/projecteuler/**"]

to exclude a package *.projecteuler.*

and test {} on project level, not nested in jacocoTestReport

Solution 4

For Gradle6 Use something like below, because they made classDirectories as final, we cannot re-assign it, but a setter method exists classDirectories.setFrom which can be utilized

    jacocoTestReport {
    reports {
        xml.enabled true
        html.enabled true
        html.destination file("$buildDir/reports/jacoco")
    }

    afterEvaluate {
        classDirectories.setFrom(files(classDirectories.files.collect {
            fileTree(dir: it,
                    exclude: ['**/server/**',
                              '**/model/**',
                              '**/command/**'
                    ]
            )
        }))
    }
}

Solution 5

In order to filter in jacoco report, exclusion need to be done in two task jacocoTestReport and jacocoTestCoverageVerification.

sample code

    def jacocoExclude = ['**/example/**', '**/*Module*.class']

    jacocoTestReport {
        afterEvaluate {
            getClassDirectories().setFrom(classDirectories.files.collect {
                fileTree(dir: it, exclude: jacocoExclude)
            })
        }
    }

    jacocoTestCoverageVerification {
        afterEvaluate {
            getClassDirectories().setFrom(classDirectories.files.collect {
                fileTree(dir: it, exclude: jacocoExclude)
            })
        }

        ...
    }



Share:
122,814

Related videos on Youtube

Jared Burrows
Author by

Jared Burrows

My Site: http://jaredsburrows.com/ My Email: [email protected] My Apps: http://burrowsapps.com/ **Android Apps** **Github** **LinkedIn** **Twitter**

Updated on January 19, 2022

Comments

  • Jared Burrows
    Jared Burrows over 2 years

    Problem:

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

    Related Documentation:

    I have read the following documentation:

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

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

    Official 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 )

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

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

    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 coverage reports?

    • Steve Peak
      Steve Peak about 9 years
      A third party option (FD I'm founder of): If you upload reports to Codecov you can ignore any files you like after the fact in the features section of the product. Thanks.
    • Jared Burrows
      Jared Burrows about 9 years
      @StevePeak So you can filter by packages online using Codecov? Also, I saw the Github, what about Android support, I saw Java. I should still have to send you all of the reports then filter after vs filtering before.
    • Steve Peak
      Steve Peak about 9 years
      You can filter based on a regexp method of any filed you do not want to include. All java is supported via Jacoco reports. Just filtering after the fact on Codecov works. It will remember your filters and apply it to all future reports. Thanks!
    • Vivin Paliath
      Vivin Paliath over 8 years
      I'm curious; what does the excludes from the official documentation actually do then? Is it pretty much useless?
    • Vampire
      Vampire over 4 years
      That excludes is not on the coverage task, but on the test task. It excludes files from being instrumented by JaCoCo and thus coverage being recorded. You can use this if you don't want to record coverage for some classes, if you cannot because of some conflict with another instrumenting agent, or because you pre-instrumented classes. This will not exclude a class from the report, especially in the last case mentioned, this would be a horrible idea.
  • Jared Burrows
    Jared Burrows about 9 years
    Alright, thank you for confirming that my findings are correct! I hope they make it easier to filter in the future or simply document how to filter using Gradle.
  • Jared Burrows
    Jared Burrows almost 9 years
    @BradPitcher No problem! It took me a while to find the right answer. It just seems so "hackish". I hope they come up with a nicer way.
  • Pedro Henrique
    Pedro Henrique over 8 years
    So, what is the correct approach if I just want to exclude one class from package?
  • Jared Burrows
    Jared Burrows over 8 years
    Something like: exclude: ['**/*Test*.*'])
  • Asker
    Asker over 8 years
    I get the error Gradle DSL method not found: 'jacocoTestReport()'. What could be wrong?
  • Jared Burrows
    Jared Burrows over 8 years
    @Asker, It looks like you are not applying the plugin: apply plugin: jacoco.
  • Asker
    Asker over 8 years
    I added apply plugin: 'jacoco' right after apply plugin: 'com.android.application'. I think it should be ok?
  • Asker
    Asker over 8 years
    now I restarted Android studio and get the following Errow "Cannot get property 'files' on null object". Any ideas?
  • Jared Burrows
    Jared Burrows over 8 years
    jacocoTestReport only works with both jacoco and java plugins. This is not for Android. Please see my repo here for android: github.com/jaredsburrows/android-gradle-java-template/blob/…
  • Asker
    Asker over 8 years
    @JaredBurrows Hi, thank you for your answer. How do i run my InstrumentationTests with this setup? They are saved in this folder "app\src\androidTest".
  • Syed Ali
    Syed Ali over 7 years
    @JaredBurrows this link for android solution is broken. Can you please share it again or add it to your answer? Thanks
  • Jared Burrows
    Jared Burrows over 7 years
    @sttaq Thanks. I added it in the answer and check it out here: github.com/jaredsburrows/android-gradle-java-app-template/bl‌​ob/….
  • Wonko the Sane
    Wonko the Sane almost 7 years
    Side note - I've found that excluding **/*Constants*.* (using wildcard for extension) will exclude a file called Constants.java but **/*Constants*.java (explicitly providing the extension) will not.
  • Aditya Peshave
    Aditya Peshave over 6 years
    In my case it is not ACTUALLY excluding them from calculation but it is just not showing them on the report. does it have to do under beforeEvaluate ?
  • Amir Pashazadeh
    Amir Pashazadeh about 6 years
    Is there any way to exclude a source set from inclusion in jacoco report? I want to exclude all source files which are located in generated/java/ instead of main/java.
  • Randy
    Randy over 5 years
    Just saw this again. This was taken directly from a working config. Perhaps your version of Gradle and Jacoco were different than mine. Sorry.
  • Mohamed El-Beltagy
    Mohamed El-Beltagy almost 5 years
    Or simply use classDirectories.from (to append to the list instead of overriding list)
  • Thunderforge
    Thunderforge almost 5 years
    The classDirectories = results in this warning. The JacocoReportBase.setClassDirectories(FileCollection) method has been deprecated. This is scheduled to be removed in Gradle 6.0. Use getClassDirectories().from(...). It would be great to show a solution compatible with Gradle 6.0.
  • tschumann
    tschumann over 4 years
    This seems to give the classes 0% coverage rather than omit them altogether. I'm using JaCoCi 0.8.5 and Gradle 6.0
  • WesternGun
    WesternGun over 4 years
    You will add [] after exclude: to include several paths.
  • Dargenn
    Dargenn about 4 years
    Excellent, I use gradle 6.0.1 and this solution worked for me.
  • Brice
    Brice almost 4 years
    This the right way to tell jacoco to not meddle with some classes, other approaches only affect the reporting part.
  • Gus
    Gus almost 4 years
    coverageExcludeClasses doesn't appear to be a thing in JaCoCo/Gradle
  • lance-java
    lance-java over 3 years
    This won't work for a clean build. afterEvaluate runs in Gradle's configuration phase which is before any tasks have executed and before any classes have been compiled. So the classes dirs will be empty
  • user9869932
    user9869932 over 3 years
    getting Cannot set the value of read-only property 'classDirectories' for task ':jacocoTestReport' of type org.gradle.testing.jacoco.tasks.JacocoReport using this configuration. Using gradle 5.6 and Java 8
  • krishna110293
    krishna110293 over 3 years
    this worked, can someone please explain what exactly is happening
  • tkruse
    tkruse over 3 years
    I have changed the acccepted answer to reflect this change
  • gsmachado
    gsmachado about 3 years
    Or, even, use getClassDirectories().from().
  • Karthik Reddy
    Karthik Reddy about 3 years
    I am trying to exclude my dtos and i am using the below code. But it is not working Please let me know if i am missing anything here. Tried in build.gradle jacocoTestReport { afterEvaluate { classDirectories.setFrom(files(classDirectories.files.collec‌​t { fileTree(dir: it, exclude: '/dto/') })) } }
  • Karthik Reddy
    Karthik Reddy about 3 years
    I am trying to use the below snippet in build.gradle to exclude my dtos but it is not working. I am using gradle 6.6.1 version. Let me know if any changes jacocoTestReport { reports { xml.enabled true html.enabled true html.destination file("$buildDir/reports/jacoco") } afterEvaluate { classDirectories.setFrom(files(classDirectories.files.collec‌​t { fileTree(dir: it, exclude: ['/dto/' ] ) })) } }
  • Aleksandr
    Aleksandr over 2 years
    Hey, your version throws the following exception message: "Cannot set the value of read-only property 'classDirectories'". Fixed with change classDirectories -> classDirectories.from .But unfortunately my package still exists inside of the report