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.