如何从使用Gradle的JaCoCo测试报告中排除隐式Groovy闭包类

bqujaahr  于 2023-04-06  发布在  其他
关注(0)|答案(2)|浏览(171)

如果你在Groovy项目上使用JaCoCo,你会在覆盖率报告中得到很多隐式创建的闭包类。链接到那些的源代码,是封闭类。封闭类的覆盖率报告也包含闭包覆盖率,所以它不会给覆盖率报告增加任何价值。更糟糕的是,它伪造了覆盖率报告,因为要在闭包中覆盖的语句在总体统计中被计算两次。
那么,如何从生成的JaCoCo覆盖报告中排除这些闭包呢?

gz5pxeao

gz5pxeao1#

您可以使用下面的代码片段从JaCoCo记录中排除隐式闭包类,但这并不妨碍在封闭类中记录语句

test {
    jacoco.excludes = ['**/*$*_closure*']
}

使用该片段,不再记录覆盖率,但现在所有闭包在报告中显示为0%覆盖率,因此也减少了整体覆盖率统计。
添加以下代码片段将从JaCoCo报告中删除闭包类,从而也将给予更有意义的总体统计数据。上面的代码片段并不是真的必要的,它只是带来了一点性能改进,因为报告不需要记录和转换覆盖率,所以我建议使用这两个代码片段。

jacocoTestReport {
    doFirst {
        classDirectories = classDirectories.collect { fileTree(it) { exclude '**/*$*_closure*' } }.sum()
    }
}

如果您有多个TestJacocoReport任务要以这种方式修改,当然也可以像

tasks.withType(Test) {
    jacoco.excludes = ['**/*$*_closure*']
}

tasks.withType(JacocoReport) {
    doFirst {
        classDirectories = classDirectories.collect { fileTree(it) { exclude '**/*$*_closure*' } }.sum()
    }
}

更新:

这里是最后一个例子的重新制作版本,使用Gradle 8.0.2 forKotlinDSL:

tasks.withType<Test>().configureEach {
    the<JacocoTaskExtension>().excludes = listOf("**/*$*_closure*")
}

afterEvaluate {
    tasks.withType<JacocoReport>().configureEach {
        classDirectories.setFrom(
            classDirectories
                .asFileTree
                .matching { exclude("**/*$*_closure*") }
                .toList()
        )
    }
}

afterEvaluate当然是邪恶的,但在这种情况下是必要的。在doFirst中更改配置,从而在执行阶段更邪恶,但在这种情况下更可靠,但不再工作,因为属性在执行阶段是只读的。

vm0i2vca

vm0i2vca2#

Vampire's answer在我使用Gradle 6.6.1时不起作用。下面的代码片段可以完成这项工作:

tasks.withType(Test) {
    jacoco.excludes = ['**/*$*_closure*']
    finalizedBy jacocoTestReport // report is always generated after tests run
}

jacocoTestReport {
    afterEvaluate {
        classDirectories.setFrom(files(classDirectories.files.collect {
            fileTree(dir: it, excludes: ['**/*$*_closure*'])
        }))
    }

    dependsOn test // tests are required to run before generating the report
}

相关问题