Filtern Sie JaCoCo-Abdeckungsberichte mit Gradle

112

Problem:

Ich habe ein Projekt mit und ich möchte in der Lage sein, bestimmte Klassen und / oder Pakete zu filtern.

Dazugehörige Dokumentation:

Ich habe die folgende Dokumentation gelesen:

Offiziell Website: http://www.eclemma.org/jacoco/index.html

Offiziell Dokumente für : https://gradle.org/docs/current/userguide/jacoco_plugin.html

Offiziell GithubProbleme, die an der Berichterstattung arbeiten: https://github.com/jacoco/jacoco/wiki/FilteringOptions https://github.com/jacoco/jacoco/issues/14

Verwandte StackOverflow-Links:

JaCoCo & Gradle - Filteroptionen (Keine Antwort)

Schließen Sie Pakete aus dem Jacoco-Bericht mit Sonarrunner und Gradle aus (nicht mit)

JaCoCo - JSP vom Bericht ausschließen (es scheint zu funktionieren, Ich benutze )

Maven Jacoco-Konfiguration - Schließen Sie Klassen / Pakete von Berichten aus, die nicht funktionieren (es scheint zu funktionieren, Ich benutze )

JaCoCo Gradle Plugin ausschließen (Konnte dies nicht zum Laufen bringen )

Gradle Jacoco - Berichterstattungsberichte enthalten Klassen, die in der Konfiguration ausgeschlossen sind (Scheint sehr nahe, es hat verwendet doFirst, hat bei mir nicht funktioniert)

Beispiel für das, was ich versucht habe:

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"]
        }
    }
}

Frage:

Wie kann ich bestimmte Pakete und Klassen beim Generieren der ausschließen? Berichterstattungsberichte?

Jared Burrows
quelle
Eine Option eines Drittanbieters (FD, dessen Gründer ich bin): Wenn Sie Berichte in Codecov hochladen, können Sie alle gewünschten Dateien nachträglich im Abschnitt "Funktionen" des Produkts ignorieren . Vielen Dank.
Steve Peak
@StevePeak Sie können also packagesonline filtern Codecov? Außerdem habe ich gesehen Github, was ist mit AndroidUnterstützung, die ich gesehen habe Java. Ich sollte Ihnen immer noch alle Berichte senden müssen, um danach zu filtern und vorher zu filtern.
Jared Burrows
Sie können nach einer Regexp-Methode für alle Dateien filtern, die Sie nicht einschließen möchten. Alle Java wird über Jacoco-Berichte unterstützt. Nur nach Codecov zu filtern, funktioniert. Es speichert Ihre Filter und wendet sie auf alle zukünftigen Berichte an. Vielen Dank!
Steve Peak
6
Ich bin neugierig; Was bedeutet die excludesvon der offiziellen Dokumentation tatsächlich tun dann? Ist es so ziemlich nutzlos?
Vivin Paliath
Das excludesbetrifft nicht die Abdeckungsaufgabe, sondern die Testaufgabe. Es schließt aus, dass Dateien von JaCoCo instrumentiert und somit die Berichterstattung aufgezeichnet wird. Sie können dies verwenden, wenn Sie für einige Klassen keine Abdeckung aufzeichnen möchten, wenn Sie dies aufgrund eines Konflikts mit einem anderen Instrumentierungsagenten nicht können oder weil Sie Klassen vorinstrumentiert haben. Dies schließt eine Klasse nicht aus dem Bericht aus, insbesondere im zuletzt genannten Fall wäre dies eine schreckliche Idee.
Vampir

Antworten:

113

Danke an Yannick Welsch:

Nachdem ich Google durchsucht, die Gradle-Dokumente gelesen und ältere StackOverflow-Beiträge durchgesehen hatte, fand ich diese Antwort im Official Foren!

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

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

Lösung für meine build.gradleJava / Groovy-Projekte:

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

Wie Sie sehen, konnte ich erfolgreich weitere hinzufügen, exclude:um einige Pakete zu filtern.

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

Benutzerdefinierte Aufgaben für andere Projekte wie 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/**'])
        })
    }
}

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

Jared Burrows
quelle
1
@BradPitcher Kein Problem! Ich habe eine Weile gebraucht, um die richtige Antwort zu finden. Es scheint einfach so "hackisch". Ich hoffe, sie haben einen schöneren Weg gefunden.
Jared Burrows
Was ist also der richtige Ansatz, wenn ich nur eine Klasse vom Paket ausschließen möchte?
Pedro Henrique
2
So etwas wie:exclude: ['**/*Test*.*'])
Jared Burrows
1
jacocoTestReportfunktioniert nur mit beiden jacocound javaPlugins. Dies ist nicht für Android. Bitte sehen Sie mein Repo hier für Android: github.com/jaredsburrows/android-gradle-java-template/blob/…
Jared Burrows
9
Die classDirectories =Ergebnisse in dieser Warnung. The JacocoReportBase.setClassDirectories(FileCollection) method has been deprecated. This is scheduled to be removed in Gradle 6.0. Use getClassDirectories().from(...). Es wäre großartig, eine Lösung zu zeigen, die mit Gradle 6.0 kompatibel ist.
Thunderforge
58

Für Gradle Version 5.x classDirectories = files(...)gibt das eine Warnung vor Verfall aus und funktioniert ab Gradle 6.0 überhaupt nicht. Dies ist die nicht veraltete Methode zum Ausschließen von Klassen:

jacocoTestReport {
    afterEvaluate {
        classDirectories.setFrom(files(classDirectories.files.collect {
            fileTree(dir: it, exclude: 'com/exclude/**')
        }))
    }
}
uwe
quelle
2
Oder verwenden Sie einfach classDirectories.from (um an die Liste anzuhängen, anstatt die Liste zu überschreiben)
Mohamed El-Beltagy
1
Sie werden []nach hinzufügen exclude: , um mehrere Pfade einzuschließen.
WesternGun
Hervorragend, ich benutze Gradle 6.0.1 und diese Lösung hat bei mir funktioniert.
Dargenn
14

Für mich ist es gut, damit zu arbeiten

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

Wie in der Dokumentation https://docs.gradle.org/current/userguide/jacoco_plugin.html#N16E62 angegeben und ursprünglich gefragt, lautet die Antwort:

Also, wenn Sie mich fragen: Es ist keine Frage von

excludes = ["projecteuler/**"]

oder

excludes += ["projecteuler/**"]

aber

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

ein Paket ausschließen *.projecteuler.*

und test {}auf Projektebene nicht verschachteltjacocoTestReport

childno͡.de
quelle
1
Dies scheint den Klassen eine Abdeckung von 0% zu geben, anstatt sie ganz wegzulassen. Ich benutze JaCoCi 0.8.5 und Gradle 6.0
tschumann
Dies ist der richtige Weg, um Jacoco anzuweisen, sich nicht in einige Klassen einzumischen. Andere Ansätze wirken sich nur auf den Berichtsteil aus.
Brice
9

Für Gradle6 Verwenden Sie etwas wie das Folgende, da es gemacht wurde classDirectories as final, können wir es nicht neu zuweisen, aber es gibt eine Setter-Methode, classDirectories.setFromdie verwendet werden kann

    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
quelle
6

Hier ist eine Lösung für dieses Problem in ANT. Dies kann an Gradle angepasst werden, indem unter der jacocoTestReportAufgabe Folgendes hinzugefügt wird . Obwohl dies von jacoco nicht wirklich dokumentiert ist, scheint es die einzige Möglichkeit zu sein, die Testergebnisse vorerst zu filtern.

afterEvaluate {
    classDirectories = files(classDirectories.files.collect {
        fileTree(dir: it, exclude: 'excluded/files/**')
    })
}
Andre Compagno
quelle
Okay, danke, dass Sie bestätigt haben, dass meine Ergebnisse korrekt sind! Ich hoffe, sie erleichtern das Filtern in Zukunft oder dokumentieren einfach, wie mit Gradle gefiltert wird.
Jared Burrows
Gibt es eine Möglichkeit, einen Quellensatz von der Aufnahme in den Jacoco-Bericht auszuschließen? Ich möchte alle Quelldateien ausschließen, die sich in generated/java/statt befinden main/java.
Amir Pashazadeh
4

Das ist schon eine Weile weg, aber ich bin gerade darauf gestoßen. Ich hatte mit allen notwendigen Ausschlüssen zu kämpfen. Ich fand es viel einfacher für mich. Wenn Sie dem Maven-Projektlayoutstil / src / main / java und / src / test / java folgen, müssen Sie buildDir / classes / main einfach wie folgt in Ihre classDirectories- Konfiguration einfügen :

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
                     ]
        )
    }
}
Geil
quelle
Hab das gerade wieder gesehen. Dies wurde direkt aus einer funktionierenden Konfiguration übernommen. Vielleicht war Ihre Version von Gradle und Jacoco anders als meine. Es tut uns leid.
Randy
4

Der folgende Code schließt Klassen ebenfalls von der Überprüfung der Abdeckung aus:

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

In einigen Kommentaren wurde die Abwertungswarnung erwähnt. zum lösen benutze einfach den getter:

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

Um im Jacoco-Bericht zu filtern, muss der Ausschluss in zwei Aufgaben jacocoTestReportund erfolgen jacocoTestCoverageVerification.

Beispielcode

    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
quelle
0

Fügen Sie die folgende Konfiguration in die Datei gradle.properties ein

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

Bharat
quelle
coverageExcludeClassesscheint in JaCoCo / Gradle
Gus