Filtrer les rapports de couverture JaCoCo avec Gradle

113

Problème:

J'ai un projet avec et je veux pouvoir filtrer certaines classes et / ou packages.

Documentation connexe:

J'ai lu la documentation suivante:

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

Officiel documents pour : https://gradle.org/docs/current/userguide/jacoco_plugin.html

Officiel Githubproblèmes, travail sur la couverture: https://github.com/jacoco/jacoco/wiki/FilteringOptions https://github.com/jacoco/jacoco/issues/14

Liens StackOverflow connexes:

JaCoCo & Gradle - Options de filtrage (pas de réponse)

Exclure les packages du rapport Jacoco à l'aide de Sonarrunner et Gradle (sans utiliser)

JaCoCo - exclure JSP du rapport (cela semble fonctionner pour, J'utilise )

Configuration Maven Jacoco - Exclure les classes / packages du rapport ne fonctionne pas (cela semble fonctionner pour, J'utilise )

Exclusion du plugin JaCoCo gradle (impossible de faire fonctionner cela)

Gradle Jacoco - les rapports de couverture incluent les classes exclues de la configuration (semble très proche, il a utilisé doFirst, n'a pas fonctionné pour moi)

Exemple de ce que j'ai essayé:

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:

Comment puis-je exclure certains packages et classes lors de la génération du rapports de couverture?

Jared Burrows
la source
Une option tierce (FD dont je suis le fondateur): Si vous téléchargez des rapports sur Codecov, vous pouvez ignorer les fichiers que vous aimez après coup dans la section des fonctionnalités du produit. Merci.
Steve Peak
@StevePeak Vous pouvez donc filtrer en packagesligne en utilisant Codecov? Aussi, j'ai vu le Github, qu'en est-il du Androidsoutien, j'ai vu Java. Je devrais encore avoir à vous envoyer tous les rapports puis filtrer après vs filtrage avant.
Jared Burrows
Vous pouvez filtrer en fonction d'une méthode d'expression régulière de tout fichier que vous ne souhaitez pas inclure. Tous les java sont pris en charge via les rapports Jacoco. Le simple filtrage après coup sur Codecov fonctionne. Il se souviendra de vos filtres et les appliquera à tous les rapports futurs. Merci!
Steve Peak
6
Je suis curieux; A quoi sert excludesde la documentation officielle fait faire alors? Est-ce à peu près inutile?
Vivin Paliath
Ce excludesn'est pas sur la tâche de couverture, mais sur la tâche de test. Il exclut les fichiers d'être instrumentés par JaCoCo et donc d'enregistrer la couverture. Vous pouvez l'utiliser si vous ne souhaitez pas enregistrer la couverture pour certaines classes, si vous ne pouvez pas en raison d'un conflit avec un autre agent d'instrumentation ou parce que vous avez pré-instrumenté des classes. Cela n'exclura pas une classe du rapport, surtout dans le dernier cas mentionné, ce serait une idée horrible.
Vampire le

Réponses:

115

Merci à Yannick Welsch:

Après avoir recherché Google, lu les documents Gradle et parcouru d'anciens articles StackOverflow, j'ai trouvé cette réponse sur le site officiel forums!

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

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

Solution à mes build.gradleprojets Java / Groovy:

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

Comme vous pouvez le voir, j'ai réussi à en ajouter exclude:afin de filtrer quelques paquets.

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

Tâches personnalisées pour d'autres projets tels qu'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

Jared Burrows
la source
1
@BradPitcher Pas de problème! Il m'a fallu un certain temps pour trouver la bonne réponse. Cela semble tellement "hackish". J'espère qu'ils trouveront une meilleure façon.
Jared Burrows
Alors, quelle est la bonne approche si je veux simplement exclure une classe du package?
Pedro Henrique
2
Quelque chose comme:exclude: ['**/*Test*.*'])
Jared Burrows
1
jacocoTestReportne fonctionne qu'avec les plugins jacocoet java. Ce n'est pas pour Android. Veuillez voir mon dépôt ici pour Android: github.com/jaredsburrows/android-gradle-java-template/blob
Jared Burrows
9
Les classDirectories =résultats dans cet avertissement. The JacocoReportBase.setClassDirectories(FileCollection) method has been deprecated. This is scheduled to be removed in Gradle 6.0. Use getClassDirectories().from(...). Ce serait formidable de montrer une solution compatible avec Gradle 6.0.
Thunderforge
61

Pour Gradle version 5.x, le classDirectories = files(...)donne un avertissement d'obsolescence et ne fonctionne pas du tout à partir de Gradle 6.0.C'est la manière non préconisée d'exclure des classes:

jacocoTestReport {
    afterEvaluate {
        classDirectories.setFrom(files(classDirectories.files.collect {
            fileTree(dir: it, exclude: 'com/exclude/**')
        }))
    }
}
uwe
la source
2
Ou utilisez simplement classDirectories.from (pour ajouter à la liste au lieu de remplacer la liste)
Mohamed El-Beltagy
1
Vous allez ajouter []après exclude: pour inclure plusieurs chemins.
WesternGun
Excellent, j'utilise gradle 6.0.1 et cette solution a fonctionné pour moi.
Dargenn le
14

pour moi, c'est bien de travailler avec

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

comme indiqué dans la documentation https://docs.gradle.org/current/userguide/jacoco_plugin.html#N16E62 et initialement demandé, la réponse est:

donc si vous me demandez: ce n'est pas une question de

excludes = ["projecteuler/**"]

ou

excludes += ["projecteuler/**"]

mais

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

pour exclure un package *.projecteuler.*

et test {}au niveau du projet, non imbriqué dansjacocoTestReport

childno͡.de
la source
1
Cela semble donner aux classes une couverture de 0% plutôt que de les omettre complètement. J'utilise JaCoCi 0.8.5 et Gradle 6.0
tschumann
C'est la bonne façon de dire à jacoco de ne pas se mêler de certaines classes, d'autres approches n'affectent que la partie rapport.
Brice le
9

Pour Gradle6 Utilisez quelque chose comme ci-dessous, car ils ont fait classDirectories as final, nous ne pouvons pas le réattribuer, mais une méthode de setter existe classDirectories.setFromqui peut être utilisée

    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/**'
                    ]
            )
        }))
    }
}
Ankur Srivastava
la source
6

Voici une solution à ce problème dans ANT. Cela peut être adapté pour graduer en ajoutant ce qui suit sous la jacocoTestReporttâche. Bien que cela ne soit pas vraiment documenté par jacoco, cela semble être le seul moyen de filtrer les résultats des tests pour le moment.

afterEvaluate {
    classDirectories = files(classDirectories.files.collect {
        fileTree(dir: it, exclude: 'excluded/files/**')
    })
}
André Compagno
la source
Très bien, merci d'avoir confirmé que mes conclusions sont correctes! J'espère qu'ils faciliteront le filtrage à l'avenir ou simplement documenter comment filtrer à l'aide de Gradle.
Jared Burrows
Existe-t-il un moyen d'exclure un ensemble source de l'inclusion dans le rapport Jacoco? Je souhaite exclure tous les fichiers source qui se trouvent dans generated/java/au lieu de main/java.
Amir Pashazadeh
4

Cela fait un moment, mais je viens de le découvrir. Je luttais avec toutes les exclusions nécessaires. J'ai trouvé que c'était quelque chose de beaucoup plus simple pour moi. Si vous suivez le style de mise en page du projet Maven / src / main / java et / src / test / java, vous devez simplement mettre buildDir / classes / main dans votre configuration classDirectories comme ceci:

afterEvaluate {
    jacocoTestReport {
        def coverageSourceDirs = ['src/main/java']
        reports {
            xml.enabled false
            csv.enabled false
            html.destination "${buildDir}/reports/jacocoHtml"
        }
        sourceDirectories = files(coverageSourceDirs)
        classDirectories = fileTree(
                dir: "${project.buildDir}/classes/main",
                excludes: [
                      //whatever here like JavaConfig etc. in /src/main/java
                     ]
        )
    }
}
Excité
la source
Je viens de revoir ça. Cela a été pris directement à partir d'une configuration de travail. Peut-être que votre version de Gradle et Jacoco était différente de la mienne. Désolé.
Randy
4

Le code ci-dessous exclut également les classes de la vérification de la couverture:

jacocoTestCoverageVerification {
    afterEvaluate {
        classDirectories = files(classDirectories.files.collect {
            fileTree(dir: "${project.buildDir}/classes/main",
                    exclude: ['**/packagename/**'])
        })
    }
}
euh-han
la source
2

certains commentaires mentionnaient l'avertissement de dépréciation. pour résoudre il suffit d'utiliser le getter:

afterEvaluate {
    getClassDirectories().from(files(classDirectories.files.collect {
        fileTree(dir: it, exclude: 'com/blah/**')
    }))
}
riiich
la source
2

Afin de filtrer dans le rapport jacoco, l'exclusion doit être effectuée en deux tâches jacocoTestReport et jacocoTestCoverageVerification.

exemple de 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)
            })
        }

        ...
    }


WIlkins LIang
la source
0

ajouter ci-dessous la configuration dans le fichier gradle.properties

coverageExcludeClasses=["com.example.package.elasticsearch.*", "com.example.package2.*",]

Bharat
la source
coverageExcludeClassesne semble pas être une chose dans JaCoCo / Gradle
Gus