Filtruj raporty pokrycia JaCoCo za pomocą Gradle


113

Problem:

Mam projekt z i chcę mieć możliwość filtrowania określonych klas i / lub pakietów.

Powiązana dokumentacja:

Przeczytałem następującą dokumentację:

Urzędnik site: http://www.eclemma.org/jacoco/index.html

Urzędnik dokumenty dla : https://gradle.org/docs/current/userguide/jacoco_plugin.html

Urzędnik Githubzagadnienia, praca nad zasięgiem: https://github.com/jacoco/jacoco/wiki/FilteringOptions https://github.com/jacoco/jacoco/issues/14

Powiązane łącza StackOverflow:

JaCoCo i Gradle - Opcje filtrowania (brak odpowiedzi)

Wyklucz pakiety z raportu Jacoco za pomocą Sonarrunner i Gradle (nie używa)

JaCoCo - wyklucz JSP z raportu (wydaje się, że działa w przypadku, Ja używam )

Konfiguracja Maven Jacoco - wykluczenie klas / pakietów z raportu nie działa (wydaje się działać dla, Ja używam )

Wykluczenie wtyczki JaCoCo gradle (nie udało się tego uruchomić)

Gradle Jacoco - raporty pokrycia obejmują klasy wykluczone w konfiguracji (Wydaje się bardzo zbliżone, używane doFirst, nie działały u mnie)

Przykład tego, czego próbowałem:

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

Pytanie:

Jak mogę wykluczyć niektóre pakiety i klasy podczas generowania pliku raporty zasięgu?


Opcja strony trzeciej (FD, którego jestem założycielem): Jeśli przesyłasz raporty do Codecov , możesz zignorować dowolne pliki po fakcie w sekcji funkcji produktu. Dzięki.
Steve Peak

@StevePeak Więc możesz filtrować packagesonline używając Codecov? Widziałem też Github, co z Androidobsługą, widziałem Java. Powinienem nadal wysyłać Ci wszystkie raporty, a następnie filtrować po a wcześniej filtrować.
Jared Burrows

Możesz filtrować na podstawie metody wyrażenia regularnego dowolnego pola, którego nie chcesz uwzględniać. Cała java jest obsługiwana przez raporty Jacoco. Po prostu filtrowanie po fakcie w Codecov działa. Zapamięta Twoje filtry i zastosuje je do wszystkich przyszłych raportów. Dzięki!
Steve Peak

6
Jestem ciekawy; co excludeswłaściwie robi oficjalna dokumentacja ? Czy to jest prawie bezużyteczne?
Vivin Paliath

To excludesnie dotyczy zadania pokrycia, ale zadania testowego. Wyklucza to pliki z instrumentowania przez JaCoCo, a tym samym z nagrywania relacji. Możesz tego użyć, jeśli nie chcesz rejestrować pokrycia niektórych klas, jeśli nie możesz tego zrobić z powodu konfliktu z innym agentem instrumentacji lub z powodu wcześniejszego oprzyrządowania klas. Nie wykluczy to klasy z raportu, zwłaszcza w ostatnim wymienionym przypadku byłby to okropny pomysł.
Vampire

Odpowiedzi:


115

Dzięki Yannick Welsch:

Po przeszukaniu Google, przeczytaniu dokumentów Gradle i przejrzeniu starszych postów StackOverflow, znalazłem tę odpowiedź w oficjalnym fora!

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

Źródło: https://issues.gradle.org/browse/GRADLE-2955

Rozwiązanie dla moich build.gradleprojektów 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/**'])
        })
    }
}

Jak widać, udało mi się dodać więcej exclude:, aby przefiltrować kilka pakietów.

Źródło: https://github.com/jaredsburrows/CS-Interview-Questions/blob/master/build.gradle

Niestandardowe zadania dla innych projektów, takich jak 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/**'])
        })
    }
}

Źródło: https://github.com/jaredsburrows/android-gradle-java-app-template/blob/master/gradle/quality.gradle#L59


1
@BradPitcher Nie ma problemu! Znalezienie właściwej odpowiedzi zajęło mi trochę czasu. To po prostu wydaje się takie „hakerskie”. Mam nadzieję, że wymyślą lepszy sposób.
Jared Burrows

Jakie jest więc prawidłowe podejście, jeśli chcę tylko wykluczyć jedną klasę z pakietu?
Pedro Henrique

2
Coś w rodzaju:exclude: ['**/*Test*.*'])
Jared Burrows

1
jacocoTestReportdziała tylko z wtyczkami jacocoi i java. To nie jest dla Androida. Zobacz moje repozytorium tutaj dla Androida: github.com/jaredsburrows/android-gradle-java-template/blob/…
Jared Burrows

9
Te classDirectories =wyniki w tym ostrzeżeniem. The JacocoReportBase.setClassDirectories(FileCollection) method has been deprecated. This is scheduled to be removed in Gradle 6.0. Use getClassDirectories().from(...). Byłoby wspaniale pokazać rozwiązanie kompatybilne z Gradle 6.0.
Thunderforge

61

W przypadku programu Gradle w wersji 5.x classDirectories = files(...)ostrzega o wycofaniu i nie działa w ogóle, począwszy od wersji Gradle 6.0. Jest to niezalecany sposób wykluczania klas:

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

2
Lub po prostu użyj classDirectories.from (aby dołączyć do listy zamiast nadpisywania listy)
Mohamed El-Beltagy

1
Dodasz []po, exclude: aby uwzględnić kilka ścieżek.
WesternGun

Świetnie, używam gradle 6.0.1 i to rozwiązanie zadziałało.
Dargenn

14

dla mnie dobrze się pracuje z

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

jak stwierdzono w dokumentacji https://docs.gradle.org/current/userguide/jacoco_plugin.html#N16E62 i początkowo zapytano, więc odpowiedź brzmi:

więc jeśli mnie zapytasz: to nie jest kwestia

excludes = ["projecteuler/**"]

lub

excludes += ["projecteuler/**"]

ale

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

aby wykluczyć pakiet *.projecteuler.*

i test {}na poziomie projektu, nie zagnieżdżone wjacocoTestReport


1
Wydaje się, że daje to klasom pokrycie na poziomie 0%, zamiast je całkowicie pomijać. Używam JaCoCi 0.8.5 i Gradle 6.0
tschumann

To właściwy sposób, aby powiedzieć Jacoco, aby nie wtrącał się do niektórych klas, inne podejścia mają wpływ tylko na część raportującą.
Brice

9

Dla Gradle6 Użyj czegoś takiego jak poniżej, ponieważ stworzyli classDirectories as final, nie możemy go ponownie przypisać, ale istnieje metoda ustawiająca, classDirectories.setFromktórą można wykorzystać

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

6

Oto rozwiązanie tego problemu w ANT. Można to dostosować do gradle, dodając w jacocoTestReportzadaniu następujące elementy . Chociaż jacoco tak naprawdę nie jest udokumentowane, wydaje się, że na razie jest to jedyny sposób na przefiltrowanie wyników testu.

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

W porządku, dziękuję za potwierdzenie, że moje ustalenia są prawidłowe! Mam nadzieję, że ułatwią one filtrowanie w przyszłości lub po prostu udokumentują sposób filtrowania za pomocą Gradle.
Jared Burrows

Czy istnieje sposób, aby wykluczyć zestaw źródłowy z uwzględnienia w raporcie jacoco? Chcę wykluczyć wszystkie pliki źródłowe, które znajdują się w generated/java/zamiast main/java.
Amir Pashazadeh

4

To było przez jakiś czas, ale właśnie się z tym spotkałem. Walczyłem ze wszystkimi potrzebnymi wykluczeniami. Okazało się, że to dla mnie coś znacznie prostszego. Jeśli podążasz za stylem projektu Maven / src / main / java i / src / test / java, po prostu musisz umieścić buildDir / classes / main w swojej konfiguracji classDirectories w następujący sposób:

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

Właśnie to widziałem. Zostało to pobrane bezpośrednio z działającej konfiguracji. Być może twoja wersja Gradle i Jacoco była inna niż moja. Przepraszam.
Randy,

4

Poniższy kod wyłącza również klasy z weryfikacji pokrycia:

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

2

w niektórych komentarzach wspomniano o ostrzeżeniu o wycofaniu. aby rozwiązać po prostu użyj gettera:

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

2

Aby filtrować w raporcie jacoco, wykluczenie należy wykonać w dwóch zadaniach jacocoTestReporti jacocoTestCoverageVerification.

przykładowy kod

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

        ...
    }



0

dodaj poniższą konfigurację w pliku gradle.properties

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


coverageExcludeClassesnie wydaje się być czymś w JaCoCo / Gradle
Gus
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.