如何验证某些排除类和 jacoco 插件的最小覆盖率?

Posted

技术标签:

【中文标题】如何验证某些排除类和 jacoco 插件的最小覆盖率?【英文标题】:How can I verify the minimum coverage with some excluded classes and with the jacoco plugin? 【发布时间】:2017-08-28 18:25:30 【问题描述】:

我需要检查新的 jacoco 任务的最小覆盖率

jacocoTestCoverageVerification

此任务在 3.4.1 gradle 版本和 jacoco 插件 >= 0.6.3 中可用

我可以运行另一个任务来生成包含分支覆盖率的 html 报告,但现在我想使用该数字使构建失败。

这是我的代码

buildscript 
    ext 
        ....
    
    repositories 
        mavenCentral()
        maven 
            ....
        
    
    dependencies 
        .....
    



apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'jacoco'

jar 
    baseName = "coverage-test"



dependencies 
    // my dependencies



eclipse 
    classpath 
         containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
         containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
    


wrapper 
    gradleVersion = '3.4.1'


jacoco 
    toolVersion = '0.7.9'


jacocoTestReport 
    reports 
        xml.enabled false
        csv.enabled false
        
    group = "Reporting"
    description = "Generate Jacoco coverage reports after running tests."
    additionalSourceDirs = files(sourceSets.main.allJava.srcDirs)

    afterEvaluate 
        classDirectories = files(classDirectories.files.collect 
            fileTree(
                dir: it,
                excludes: 
                [
                        'com/jacoco/dto/**',
                        'com/jacoco/configs/**', 
                        //and others
                ])
        )
    


jacocoTestCoverageVerification 

    //I tried this and it didn't work

  //   classDirectories = files(classDirectories.files.collect 
  //   fileTree(
  //    dir: it,
        // excludes: 
        // [
        //      'com/jacoco/dto/**',
        //      'com/jacoco/configs/**', 
        //      //and others
        // ])
  //   )

    violationRules 
        rule 
            //Also tried this and it didn't work

           // excludes = ['com/jacoco/dto/**', ...]

            limit 
                counter = 'BRANCH'
                minimum = 0.8
            
        
    

check.dependsOn jacocoTestCoverageVerification

使用 classDirectories 我收到以下错误无法在空对象上获取属性“文件”。使用第二个选项(仅排除),构建运行顺利,但不排除任何类。

【问题讨论】:

【参考方案1】:

在我的例子中,我确实想使用 BUNDLE 范围来为整体设置一个阈值,同时排除某些 packages文件

最终对我有用的是添加 classDirectories 排除,如原始问题中所建议的那样,但在 afterEvaluate 中像这样:

afterEvaluate 
        classDirectories = files(classDirectories.files.collect 
            fileTree(dir: it, exclude:  [
                    'com/example/my/package/*',
                    'com/example/service/MyApplication.class',
                    'com/google/protobuf/*'
            ])
        )
    

作为参考,完整的build.gradle 如下所示:

apply plugin: "jacoco”

jacocoTestCoverageVerification 
    afterEvaluate 
        getClassDirectories().setFrom(classDirectories.files.collect 
            fileTree(dir: it, exclude:  [
                    'com/example/my/package/*',
                    'com/example/service/MyApplication.class',
                    'com/google/protobuf/*'
            ])
        )
    

    violationRules 
        rule 
            limit 
                minimum = 0.79
            
        
    



// to run coverage verification during the build (and fail when appropriate)
check.dependsOn jacocoTestCoverageVerification  

您可以在我的博客中找到更多详细信息:http://jivimberg.io/blog/2018/04/26/gradle-verify-coverage-with-exclusions/

【讨论】:

这是完美的。我一直尝试在规则中使用排除项,但没有看到任何变化。感谢您弄清楚。投票赞成! 至少在 Gradle 6 中,这会失败并显示以下内容:Cannot set the value of read-only property 'classDirectories' for task ':jacocoTestCoverageVerification' of type org.gradle.testing.jacoco.tasks.JacocoCoverageVerification. @tschumann 替换 classDirectories = files(classDirectories.files.collect TO getClassDirectories().setFrom(classDirectories.files.collect @DaniilVolkov 是我的英雄。谢谢! 在kotlin中,可以classDirectories.setFrom( classDirectories.files.flatMap fileTree(it) exclude("**/App.class") 【参考方案2】:

您正在测量您排除的不同事物。默认的 JaCoCo 范围是“BUNDLE”,我相信这意味着整个代码。我从来没有用过。我总是只测量“CLASS”范围。看起来你正在尝试做同样的事情。

排除与范围内的元素相关。不确定它对“BUNDLE”意味着什么,但我几乎倾向于认为它要么全有,要么全无。排除项也使用不同类型的通配符。尝试更改您的配置以使用元素“CLASS”(或“PACKAGE”)。

violationRules 
    rule 
        element = 'CLASS'
        excludes = ['com.jacoco.dto.*']
        limit 
            counter = 'BRANCH'
            minimum = 0.8
        
    


check.dependsOn jacocoTestCoverageVerification

【讨论】:

顺便说一句,这是我在我的项目中尝试过的一个要点(并且它有效):gist.github.com/sm4/1cacc5d8b6d99cac84336ab4df06d1bd 这就是项目:github.com/sm4/promo-codes 是的,你是对的,我试图测量两个不同的东西。我还尝试使用您的配置添加检查规则并且它有效。谢谢!!

以上是关于如何验证某些排除类和 jacoco 插件的最小覆盖率?的主要内容,如果未能解决你的问题,请参考以下文章

Jacoco Gradle 中的最小代码覆盖率阈值

如何从android项目中的jacoco测试覆盖率报告中排除方法

使用 Jacoco 从 Sonar 中的条件覆盖范围中排除 groovy slf4j 日志记录

使用 Gradle 过滤 JaCoCo 覆盖率报告

在覆盖 JUnit 中排除文件夹 [关闭]

Maven Jacoco 配置 - 从报告中排除类/包不起作用