กรองรายงานความครอบคลุมของ JaCoCo ด้วย Gradle


118

ปัญหา:

ฉันมีโครงการกับ และฉันต้องการกรองคลาสและ / หรือแพ็คเกจบางอย่าง

เอกสารที่เกี่ยวข้อง:

ฉันได้อ่านเอกสารดังต่อไปนี้:

เป็นทางการ เว็บไซต์: http://www.eclemma.org/jacoco/index.html

เป็นทางการ เอกสารสำหรับ : https://gradle.org/docs/current/userguide/jacoco_plugin.html

เป็นทางการ Githubปัญหาเกี่ยวกับการรายงานข่าว: https://github.com/jacoco/jacoco/wiki/FilteringOptions https://github.com/jacoco/jacoco/issues/14

ลิงค์ StackOverflow ที่เกี่ยวข้อง:

JaCoCo & Gradle - ตัวเลือกการกรอง (ไม่มีคำตอบ)

ไม่รวมแพ็คเกจจากรายงาน Jacoco โดยใช้ Sonarrunner และ Gradle (ไม่ใช้ไฟล์)

JaCoCo - ไม่รวม JSP จากรายงาน (ดูเหมือนว่าจะใช้ได้กับ, ฉันใช้ )

การกำหนดค่า Maven Jacoco - ไม่รวมคลาส / แพ็คเกจจากรายงานไม่ทำงาน (ดูเหมือนว่าจะใช้ได้กับ, ฉันใช้ )

ไม่รวมปลั๊กอิน JaCoCo gradle (ไม่สามารถใช้งานได้)

Gradle Jacoco - รายงานความครอบคลุมรวมถึงคลาสที่ไม่รวมอยู่ในการกำหนดค่า (ดูเหมือนจะใกล้เคียงมากใช้doFirstแล้วไม่ได้ผลสำหรับฉัน)

ตัวอย่างสิ่งที่ฉันได้ลอง:

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

คำถาม:

ฉันจะแยกแพ็คเกจและคลาสบางอย่างได้อย่างไรเมื่อสร้างไฟล์ รายงานความครอบคลุม?


ตัวเลือกของบุคคลที่สาม (FD ฉันเป็นผู้ก่อตั้ง): หากคุณอัปโหลดรายงานไปยังCodecovคุณสามารถเพิกเฉยต่อไฟล์ใด ๆ ที่คุณชอบหลังจากข้อเท็จจริงในส่วนคุณสมบัติของผลิตภัณฑ์ ขอบคุณ.
Steve Peak

@StevePeak ดังนั้นคุณสามารถกรองโดยpackagesออนไลน์โดยใช้Codecov? นอกจากนี้ผมเห็นGithubสิ่งที่เกี่ยวกับการสนับสนุนผมเห็นAndroid Javaฉันควรจะต้องส่งรายงานทั้งหมดให้คุณจากนั้นกรองหลังเทียบกับการกรองก่อน
Jared Burrows

คุณสามารถกรองตามวิธี regexp ของไฟล์ที่คุณไม่ต้องการรวม รองรับ Java ทั้งหมดผ่านรายงาน Jacoco เพียงกรองหลังจากที่ Codecov ใช้งานได้ จะจดจำตัวกรองของคุณและนำไปใช้กับรายงานในอนาคตทั้งหมด ขอบคุณ!
Steve Peak

6
ฉันอยากรู้; สิ่งที่ไม่excludesจากเอกสารอย่างเป็นทางการจริงทำแล้ว? มันไร้ประโยชน์มากเลยเหรอ?
Vivin Paliath

นั่นexcludesไม่ได้อยู่ในงานการรายงานข่าว แต่เป็นงานทดสอบ ไม่รวมไฟล์จากการเป็นเครื่องมือโดย JaCoCo และทำให้ความครอบคลุมถูกบันทึก คุณสามารถใช้สิ่งนี้ได้หากคุณไม่ต้องการบันทึกการครอบคลุมสำหรับบางคลาสหากคุณทำไม่ได้เนื่องจากมีข้อขัดแย้งกับตัวแทนเครื่องมืออื่นหรือเนื่องจากคุณมีคลาสที่ใช้เครื่องมือล่วงหน้า นี่จะไม่รวมชั้นเรียนออกจากรายงานโดยเฉพาะอย่างยิ่งในกรณีสุดท้ายที่กล่าวถึงนี่จะเป็นความคิดที่น่ากลัว
Vampire

คำตอบ:


117

ขอบคุณYannick Welsch:

หลังจากค้นหา Google อ่านเอกสาร Gradle และอ่านโพสต์ StackOverflow รุ่นเก่าฉันพบคำตอบนี้ใน Official เว็บบอร์ด!

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

ที่มา: https://issues.gradle.org/browse/GRADLE-2955

วิธีแก้ปัญหาbuild.gradleสำหรับโปรเจ็กต์ 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/**'])
        })
    }
}

อย่างที่คุณเห็นฉันสามารถเพิ่มได้สำเร็จexclude:เพื่อกรองแพ็คเกจบางอย่าง

ที่มา: https://github.com/jaredsburrows/CS-Interview-Questions/blob/master/build.gradle

งานที่กำหนดเองสำหรับโครงการอื่น ๆ เช่น 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/**'])
        })
    }
}

ที่มา: https://github.com/jaredsburrows/android-gradle-java-app-template/blob/master/gradle/quality.gradle#L59


1
@BradPitcher ไม่มีปัญหา! ฉันใช้เวลาสักพักเพื่อค้นหาคำตอบที่ถูกต้อง ดูเหมือนว่า "แฮ็ก" ฉันหวังว่าพวกเขาจะได้วิธีที่ดีกว่านี้
Jared Burrows

ดังนั้นแนวทางที่ถูกต้องคืออะไรหากฉันต้องการแยกคลาสหนึ่งออกจากแพ็คเกจ?
Pedro Henrique

2
สิ่งที่ชอบ:exclude: ['**/*Test*.*'])
Jared Burrows

1
jacocoTestReportใช้งานได้กับทั้งสองjacocoและjavaปลั๊กอินเท่านั้น นี่ไม่ใช่สำหรับ Android โปรดดู repo ของฉันที่นี่สำหรับ android: github.com/jaredsburrows/android-gradle-java-template/blob/…
Jared Burrows

11
classDirectories =ผลในการแจ้งเตือนนี้ The JacocoReportBase.setClassDirectories(FileCollection) method has been deprecated. This is scheduled to be removed in Gradle 6.0. Use getClassDirectories().from(...). จะเป็นการดีที่จะแสดงโซลูชันที่เข้ากันได้กับ Gradle 6.0
Thunderforge

65

สำหรับ Gradle เวอร์ชัน 5.x classDirectories = files(...)คำเตือนการเลิกใช้งานจะไม่ทำงานเลยโดยเริ่มจาก Gradle 6.0 นี่เป็นวิธีที่ไม่ได้รับการสนับสนุนในการยกเว้นคลาส:

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

2
หรือใช้ classDirectories.from (เพื่อต่อท้ายรายการแทนการลบล้างรายการ)
Mohamed El-Beltagy

1
คุณจะเพิ่ม[]หลังexclude: เพื่อรวมเส้นทางต่างๆ
WesternGun

ยอดเยี่ยมฉันใช้ gradle 6.0.1 และวิธีนี้ใช้ได้ผลสำหรับฉัน
Dargenn

14

สำหรับฉันมันใช้ได้ดีกับ

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

ตามที่ระบุไว้ในเอกสาร https://docs.gradle.org/current/userguide/jacoco_plugin.html#N16E62และถามเริ่มต้นดังนั้นคำตอบคือ:

ดังนั้นถ้าคุณถามฉัน: มันไม่ใช่คำถาม

excludes = ["projecteuler/**"]

หรือ

excludes += ["projecteuler/**"]

แต่

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

เพื่อไม่รวมแพ็คเกจ *.projecteuler.*

และtest {}ในระดับโครงการไม่ซ้อนกันjacocoTestReport


1
สิ่งนี้ดูเหมือนว่าจะให้ความครอบคลุมชั้นเรียน 0% แทนที่จะละเว้นทั้งหมด ฉันใช้ JaCoCi 0.8.5 และ Gradle 6.0
tschumann

วิธีนี้เป็นวิธีที่ถูกต้องในการบอกให้ jacoco ไม่เข้าไปยุ่งกับบางชั้นเรียนวิธีอื่น ๆ จะส่งผลต่อส่วนการรายงานเท่านั้น
Brice

9

สำหรับ Gradle6 ให้ใช้สิ่งที่ต้องการด้านล่างเนื่องจากพวกเขาสร้างขึ้นclassDirectories as finalเราไม่สามารถกำหนดใหม่ได้ แต่มีเมธอด setter classDirectories.setFromซึ่งสามารถใช้ประโยชน์ได้

    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

นี่คือวิธีแก้ปัญหานี้ใน ANT สิ่งนี้สามารถปรับให้เข้ากับการไล่ระดับสีได้โดยเพิ่มสิ่งต่อไปนี้ภายใต้jacocoTestReportงาน แม้ว่า jacoco จะไม่ได้บันทึกไว้ แต่ดูเหมือนว่าจะเป็นวิธีเดียวในการกรองผลการทดสอบในตอนนี้

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

เอาล่ะขอบคุณที่ยืนยันว่าสิ่งที่ฉันค้นพบนั้นถูกต้อง! ฉันหวังว่าพวกเขาจะช่วยให้กรองได้ง่ายขึ้นในอนาคตหรือเพียงแค่บันทึกวิธีการกรองโดยใช้ Gradle
Jared Burrows

มีวิธีใดบ้างในการยกเว้นชุดแหล่งที่มาจากการรวมในรายงานจาโคโค ฉันต้องการที่จะแยกไฟล์ต้นฉบับทั้งหมดซึ่งตั้งอยู่ในแทนgenerated/java/ main/java
Amir Pashazadeh

4

นี่ออกมาสักพักแล้ว แต่ฉันเพิ่งวิ่งข้ามสิ่งนี้ ฉันกำลังดิ้นรนกับการยกเว้นทั้งหมดที่จำเป็น ฉันพบว่ามันง่ายกว่ามากสำหรับฉัน หากคุณทำตามรูปแบบโครงร่างโครงการ Maven / src / main / java และ / src / test / java คุณก็ต้องใส่buildDir / class / main ในclassDirectories config ดังนี้:

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

เพิ่งเห็นนี่อีกครั้ง สิ่งนี้นำมาจากการกำหนดค่าที่ใช้งานได้โดยตรง บางที Gradle และ Jacoco เวอร์ชันของคุณอาจแตกต่างจากของฉัน ขออภัย.
Randy

4

รหัสด้านล่างนี้ไม่รวมคลาสจากการตรวจสอบความครอบคลุมเช่นกัน:

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

2

ความคิดเห็นบางส่วนกล่าวถึงคำเตือนการเลิกใช้งาน ในการแก้ปัญหาเพียงแค่ใช้ getter:

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

2

เพื่อที่จะกรองในรายงาน jacoco ยกเว้นความจำเป็นที่จะต้องทำในสองงานและjacocoTestReportjacocoTestCoverageVerification

โค้ดตัวอย่าง

    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

เพิ่ม config ด้านล่างในไฟล์ gradle.properties

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


coverageExcludeClassesดูเหมือนจะไม่เกิดขึ้นใน JaCoCo / Gradle
Gus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.