Filter laporan cakupan JaCoCo dengan Gradle

113

Masalah:

Saya punya proyek dengan dan saya ingin dapat memfilter kelas dan / atau paket tertentu.

Dokumentasi Terkait:

Saya telah membaca dokumentasi berikut:

Resmi situs: http://www.eclemma.org/jacoco/index.html

Resmi dokumen untuk : https://gradle.org/docs/current/userguide/jacoco_plugin.html

Resmi Githubmasalah, mengerjakan liputan: https://github.com/jacoco/jacoco/wiki/FilteringOptions https://github.com/jacoco/jacoco/issues/14

Tautan StackOverflow Terkait:

JaCoCo & Gradle - Opsi Pemfilteran (Tidak ada jawaban)

Kecualikan paket dari laporan Jacoco menggunakan Sonarrunner dan Gradle (Tidak menggunakan)

JaCoCo - kecualikan JSP dari laporan (Sepertinya berfungsi untuk, Saya menggunakan )

Konfigurasi Maven Jacoco - Kecualikan kelas / paket dari laporan tidak berfungsi (Tampaknya berfungsi untuk, Saya menggunakan )

Kecualikan plugin gradle JaCoCo (Tidak dapat membuat ini berfungsi)

Gradle Jacoco - laporan cakupan menyertakan kelas yang dikecualikan dalam konfigurasi (Sepertinya sangat dekat, ini digunakan doFirst, tidak berfungsi untuk saya)

Contoh yang sudah saya coba:

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

Pertanyaan:

Bagaimana cara mengecualikan paket dan kelas tertentu saat membuat file laporan cakupan?

Jared Burrows
sumber
Opsi pihak ketiga (FD, saya pendiri): Jika Anda mengunggah laporan ke Codecov, Anda dapat mengabaikan file apa pun yang Anda suka setelah fakta di bagian fitur produk. Terima kasih.
Steve Peak
@StevePeak Jadi Anda dapat memfilter secara packagesonline menggunakan Codecov? Juga, saya melihat Github, bagaimana dengan Androiddukungan, saya melihat Java. Saya tetap harus mengirimkan semua laporan kepada Anda kemudian memfilter setelah vs memfilter sebelumnya.
Jared Burrows
Anda dapat memfilter berdasarkan metode regexp dari setiap file yang tidak ingin Anda sertakan. Semua java didukung melalui laporan Jacoco. Hanya menyaring setelah fakta di Codecov bekerja. Ini akan mengingat filter Anda dan menerapkannya ke semua laporan mendatang. Terima kasih!
Steve Peak
6
Saya penasaran; apa yang excludessebenarnya dilakukan oleh dokumentasi resmi ? Apakah itu sangat tidak berguna?
Vivin Paliath
Itu excludesbukan pada tugas cakupan, tapi pada tugas ujian. Ini mengecualikan file agar tidak diinstrumentasi oleh JaCoCo dan dengan demikian cakupan direkam. Anda dapat menggunakan ini jika Anda tidak ingin merekam liputan untuk beberapa kelas, jika Anda tidak bisa karena beberapa konflik dengan agen instrumen lain, atau karena Anda pra-instrumentasi kelas. Ini tidak akan mengecualikan kelas dari laporan, terutama dalam kasus terakhir yang disebutkan, ini akan menjadi ide yang buruk.
Vampir

Jawaban:

115

Berkat, Yannick Welsch:

Setelah mencari di Google, membaca dokumen Gradle dan melalui posting StackOverflow yang lebih lama, saya menemukan jawaban ini di Official forum!

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

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

Solusi saya build.gradleuntuk proyek 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/**'])
        })
    }
}

Seperti yang Anda lihat, saya berhasil menambahkan lebih banyak ke exclude:untuk memfilter beberapa paket.

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

Tugas khusus untuk proyek lain seperti 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/**'])
        })
    }
}

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

Jared Burrows
sumber
1
@BradPitcher Tidak masalah! Saya butuh beberapa saat untuk menemukan jawaban yang benar. Sepertinya begitu "hackish". Saya berharap mereka tampil dengan cara yang lebih baik.
Jared Burrows
Jadi, apa pendekatan yang benar jika saya hanya ingin mengecualikan satu kelas dari paket?
Pedro Henrique
2
Sesuatu seperti:exclude: ['**/*Test*.*'])
Jared Burrows
1
jacocoTestReporthanya bekerja dengan plugin jacocodan java. Ini bukan untuk Android. Silakan lihat repo saya di sini untuk android: github.com/jaredsburrows/android-gradle-java-template/blob/…
Jared Burrows
9
The classDirectories =hasil dalam peringatan ini. The JacocoReportBase.setClassDirectories(FileCollection) method has been deprecated. This is scheduled to be removed in Gradle 6.0. Use getClassDirectories().from(...). Akan sangat bagus untuk menunjukkan solusi yang kompatibel dengan Gradle 6.0.
Thunderforge
61

Untuk Gradle versi 5.x, pemberian classDirectories = files(...)peringatan penghentian dan tidak berfungsi sama sekali mulai dari Gradle 6.0 Ini adalah cara yang tidak berlaku lagi untuk mengecualikan kelas:

jacocoTestReport {
    afterEvaluate {
        classDirectories.setFrom(files(classDirectories.files.collect {
            fileTree(dir: it, exclude: 'com/exclude/**')
        }))
    }
}
uwe
sumber
2
Atau cukup gunakan classDirectories.from (untuk menambahkan daftar alih-alih menimpa daftar)
Mohamed El-Beltagy
1
Anda akan menambahkan []setelah exclude: memasukkan beberapa jalur.
WesternGun
Luar biasa, saya menggunakan gradle 6.0.1 dan solusi ini berhasil untuk saya.
Dargenn
14

bagi saya, tidak masalah bekerja dengan

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

sebagaimana tercantum dalam dokumentasi https://docs.gradle.org/current/userguide/jacoco_plugin.html#N16E62 dan pada awalnya ditanyakan jawabannya adalah:

jadi jika Anda bertanya kepada saya: ini bukan pertanyaan tentang

excludes = ["projecteuler/**"]

atau

excludes += ["projecteuler/**"]

tapi

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

untuk mengecualikan sebuah paket *.projecteuler.*

dan test {}pada tingkat proyek, tidak bertingkatjacocoTestReport

childno͡.de
sumber
1
Hal ini tampaknya memberikan cakupan kelas 0% daripada menghilangkan semuanya sama sekali. Saya menggunakan JaCoCi 0.8.5 dan Gradle 6.0
tschumann
Ini cara yang tepat untuk memberi tahu jacoco agar tidak mencampuri beberapa kelas, pendekatan lain hanya memengaruhi bagian pelaporan.
Brice
9

Untuk Gradle6 Gunakan sesuatu seperti di bawah ini, karena dibuat classDirectories as final, kita tidak dapat menetapkannya kembali, tetapi ada metode penyetel classDirectories.setFromyang dapat digunakan

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

Berikut adalah solusi untuk masalah ini di ANT. Ini dapat diadaptasi untuk gradle dengan menambahkan yang berikut di bawah jacocoTestReporttugas. Meskipun ini tidak benar-benar didokumentasikan oleh jacoco, sepertinya itu satu-satunya cara untuk memfilter hasil tes untuk saat ini.

afterEvaluate {
    classDirectories = files(classDirectories.files.collect {
        fileTree(dir: it, exclude: 'excluded/files/**')
    })
}
Andre Compagno
sumber
Baiklah, terima kasih telah mengonfirmasi bahwa temuan saya benar! Saya berharap mereka mempermudah pemfilteran di masa mendatang atau sekadar mendokumentasikan cara memfilter menggunakan Gradle.
Jared Burrows
Apakah ada cara untuk mengecualikan kumpulan sumber dari penyertaan dalam laporan jacoco? Saya ingin mengecualikan semua file sumber yang terletak di generated/java/alih-alih main/java.
Amir Pashazadeh
4

Ini sudah lama keluar, tapi saya baru saja menemukan ini. Saya berjuang dengan semua pengecualian yang dibutuhkan. Saya menemukan itu adalah sesuatu yang jauh lebih sederhana bagi saya. Jika Anda mengikuti gaya layout proyek Maven / src / main / java dan / src / test / java, Anda hanya perlu meletakkan buildDir / class / main di konfigurasi classDirectories Anda seperti ini:

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
                     ]
        )
    }
}
Randy
sumber
Baru saja melihat ini lagi. Ini diambil langsung dari konfigurasi yang berfungsi. Mungkin versi Gradle dan Jacoco Anda berbeda dengan versi saya. Maaf.
Randy
4

Kode di bawah ini juga mengecualikan kelas dari verifikasi cakupan:

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

beberapa komentar menyebutkan peringatan penghentian. untuk menyelesaikannya, cukup gunakan getter:

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

Untuk memfilter di laporan jacoco, pengecualian perlu dilakukan dalam dua tugas jacocoTestReportdan jacocoTestCoverageVerification.

Kode sampel

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

tambahkan konfigurasi di bawah ini di file gradle.properties

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

Bharat
sumber
coverageExcludeClassestampaknya tidak menjadi apa-apa di JaCoCo / Gradle
Gus