Lọc báo cáo phạm vi JaCoCo với Gradle


113

Vấn đề:

Tôi có một dự án với và tôi muốn có thể lọc các lớp và / hoặc gói nhất định.

Tài liệu liên quan:

Tôi đã đọc tài liệu sau:

Chính thức trang web: http://www.eclemma.org/jacoco/index.html

Chính thức tài liệu cho : https://gradle.org/docs/current/userguide/jacoco_plugin.html

Chính thức Githubvấn đề, làm việc về phạm vi bảo hiểm: https://github.com/jacoco/jacoco/wiki/FilteringOptions https://github.com/jacoco/jacoco/issues/14

Liên kết StackOverflow có liên quan:

JaCoCo & Gradle - Tùy chọn lọc (Không có câu trả lời)

Loại trừ các gói khỏi báo cáo Jacoco bằng Sonarrunner và Gradle (Không sử dụng)

JaCoCo - loại trừ JSP khỏi báo cáo (Nó dường như hoạt động đối với, Tôi đang dùng )

Cấu hình Maven Jacoco - Loại trừ các lớp / gói khỏi báo cáo không hoạt động (Có vẻ như hoạt động đối với, Tôi đang dùng )

Loại trừ plugin JaCoCo gradle (Không thể làm cho điều này hoạt động)

Gradle Jacoco - báo cáo phạm vi bao gồm các lớp bị loại trừ trong cấu hình (Có vẻ rất gần, nó đã được sử dụng doFirst, không hoạt động với tôi)

Ví dụ về những gì tôi đã thử:

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

Câu hỏi:

Làm cách nào để loại trừ các gói và lớp nhất định khi tạo báo cáo bao phủ?


Tùy chọn bên thứ ba (FD tôi là người sáng lập): Nếu bạn tải báo cáo lên Codecov, bạn có thể bỏ qua bất kỳ tệp nào bạn thích sau phần tính năng của sản phẩm. Cảm ơn.
Steve Peak

@StevePeak Vì vậy, bạn có thể lọc bằng packagescách sử dụng trực tuyến Codecov? Ngoài ra, tôi đã thấy Github, những gì về Androidhỗ trợ, tôi đã thấy Java. Tôi vẫn phải gửi cho bạn tất cả các báo cáo rồi lọc sau so với lọc trước.
Jared Burrows

Bạn có thể lọc dựa trên phương pháp regexp của bất kỳ tệp nào mà bạn không muốn đưa vào. Tất cả java đều được hỗ trợ thông qua báo cáo Jacoco. Chỉ lọc sau khi thực tế trên Codecov hoạt động. Nó sẽ ghi nhớ các bộ lọc của bạn và áp dụng nó cho tất cả các báo cáo trong tương lai. Cảm ơn!
Steve Peak

6
Tôi tò mò; những gì excludestừ tài liệu chính thức thực sự làm sau đó? Nó có khá nhiều vô ích?
Vivin Paliath

Đó excludeskhông phải là nhiệm vụ phủ sóng, mà là nhiệm vụ kiểm tra. Nó loại trừ các tệp khỏi được công cụ JaCoCo và do đó phạm vi được ghi lại. Bạn có thể sử dụng điều này nếu bạn không muốn ghi lại phạm vi bảo hiểm cho một số lớp học, nếu bạn không thể ghi lại vì một số xung đột với tác nhân thiết bị khác hoặc vì bạn đã cài đặt trước các lớp học. Điều này sẽ không loại trừ một lớp khỏi báo cáo, đặc biệt là trong trường hợp cuối cùng được đề cập, đây sẽ là một ý tưởng kinh khủng.
Vampire

Câu trả lời:


115

Nhờ, Yannick Welsch:

Sau khi tìm kiếm trên Google, đọc tài liệu Gradle và xem qua các bài đăng cũ hơn của StackOverflow, tôi đã tìm thấy câu trả lời này trên Official diễn đàn!

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

Nguồn: https://issues.gradle.org/browse/GRADLE-2955

Giải pháp build.gradlecho các dự án Java / Groovy của tôi :

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

Như bạn có thể thấy, tôi đã có thể thêm thành công exclude:vào để lọc một vài gói.

Nguồn: https://github.com/jaredsburrows/CS-Interview-Questions/blob/master/build.gradle

Các tác vụ tùy chỉnh cho các dự án khác như 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/**'])
        })
    }
}

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


1
@BradPitcher Không sao! Tôi đã mất một lúc để tìm ra câu trả lời thích hợp. Nó chỉ có vẻ rất "hackish". Tôi hy vọng họ nghĩ ra một cách tốt hơn.
Jared Burrows

Vì vậy, cách tiếp cận chính xác là gì nếu tôi chỉ muốn loại trừ một lớp khỏi gói?
Pedro Henrique

2
Một cái gì đó giống như:exclude: ['**/*Test*.*'])
Jared Burrows

1
jacocoTestReportchỉ hoạt động với cả hai jacocojavaplugin. Điều này không dành cho Android. Xin vui lòng xem repo của tôi ở đây cho android: github.com/jaredsburrows/android-gradle-java-template/blob/...
Jared Burrows

9
Các classDirectories =kết quả trong cảnh báo này. The JacocoReportBase.setClassDirectories(FileCollection) method has been deprecated. This is scheduled to be removed in Gradle 6.0. Use getClassDirectories().from(...). Sẽ thật tuyệt nếu hiển thị một giải pháp tương thích với Gradle 6.0.
Thunderforge

60

Đối với phiên bản Gradle 5.x, nó classDirectories = files(...)đưa ra cảnh báo không dùng nữa và hoàn toàn không hoạt động bắt đầu từ Gradle 6.0 Đây là cách loại trừ các lớp không được chấp nhận:

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

2
Hoặc đơn giản là sử dụng classDirectories.from (để append vào danh sách thay vì danh sách trọng)
Mohamed El-Beltagy

1
Bạn sẽ thêm []sau exclude: để bao gồm một số đường dẫn.
WesternGun

Tuyệt vời, tôi sử dụng gradle 6.0.1 và giải pháp này phù hợp với tôi.
Dargenn

14

đối với tôi, nó ổn khi làm việc với

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

như đã nêu trong tài liệu https://docs.gradle.org/current/userguide/jacoco_plugin.html#N16E62 và ngay lập tức được hỏi nên câu trả lời là:

vì vậy nếu bạn hỏi tôi: nó không phải là câu hỏi về

excludes = ["projecteuler/**"]

hoặc là

excludes += ["projecteuler/**"]

nhưng

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

để loại trừ một gói *.projecteuler.*

test {}ở cấp độ dự án, không được lồng trongjacocoTestReport


1
Điều này dường như cung cấp cho các lớp mức độ bao phủ là 0% thay vì bỏ qua chúng hoàn toàn. Tôi đang sử dụng JaCoCi 0.8.5 và Gradle 6.0
tschumann

Đây là cách đúng đắn để nói với jacoco không can thiệp vào một số lớp, các cách tiếp cận khác chỉ ảnh hưởng đến phần báo cáo.
Brice

9

Đối với Gradle6 Sử dụng một cái gì đó như bên dưới, bởi vì họ đã tạo classDirectories as final, chúng tôi không thể gán lại nó, nhưng có một phương thức setter classDirectories.setFromcó thể được sử dụng

    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

Đây là một giải pháp cho vấn đề này trong ANT. Điều này có thể được điều chỉnh cho phù hợp với gradle bằng cách thêm phần sau vào jacocoTestReportnhiệm vụ. Mặc dù điều này không thực sự được jacoco ghi lại, nhưng có vẻ như đây là cách duy nhất để lọc kết quả thử nghiệm lúc này.

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

Được rồi, cảm ơn bạn đã xác nhận rằng phát hiện của tôi là chính xác! Tôi hy vọng họ sẽ làm cho việc lọc dễ dàng hơn trong tương lai hoặc chỉ đơn giản là ghi lại cách lọc bằng Gradle.
Jared Burrows

Có cách nào để loại trừ một bộ nguồn không được đưa vào báo cáo jacoco không? Tôi muốn loại trừ tất cả các tệp nguồn nằm trong generated/java/đó thay vì main/java.
Amir Pashazadeh

4

Điều này đã ra trong một thời gian, nhưng tôi chỉ tình cờ gặp nó. Tôi đã đấu tranh với tất cả các loại trừ cần thiết. Tôi thấy nó là một cái gì đó đơn giản hơn nhiều đối với tôi. Nếu bạn làm theo kiểu bố cục dự án Maven / src / main / java và / src / test / java, bạn chỉ cần đặt buildDir / class / main trong cấu hình classDirectories của mình như sau:

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

Chỉ nhìn thấy điều này một lần nữa. Điều này được lấy trực tiếp từ một cấu hình đang hoạt động. Có lẽ phiên bản Gradle và Jacoco của bạn khác với tôi. Lấy làm tiếc.
Randy

4

Mã bên dưới cũng loại trừ các lớp khỏi xác minh phạm vi:

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

2

một số nhận xét đã đề cập đến cảnh báo không dùng nữa. để giải quyết chỉ cần sử dụng getter:

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

2

Để lọc trong báo cáo jacoco, việc loại trừ cần được thực hiện trong hai nhiệm vụ jacocoTestReportjacocoTestCoverageVerification.

mã mẫu

    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

thêm cấu hình bên dưới trong tệp gradle.properties

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


coverageExcludeClassesdường như không phải là một điều trong JaCoCo / Gradle
Gus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.