如何获得测试覆盖或忽略Jacoco的Kotlin数据类

问题描述 投票:5回答:5

Jacoco对Kotlin的数据类别的覆盖率为0%。如何配置它来测量覆盖率或忽略数据类?

unit-testing kotlin jacoco test-coverage
5个回答
3
投票

我正在为数据模型类的自动生成代码寻找相同测试覆盖问题的解决方案,并偶然发现: Kotlin + JaCoCo: Tuning Compiler to Skip Generated Code

解决方案:将JaCoCo插件更新为0.8.2并解决您的问题。

JaCoCo在0.8.2版本中解决了这个问题,请阅读更改日志 -

  • 在生成报告期间(GitHub#731)过滤掉用简单名称为Generated的运行时可见和不可见注释注释的类和方法。
  • 在生成报告期间,Kotlin编译器添加的没有行号的方法将被过滤掉。 Nikolay Krasko的理念和实施(GitHub#689)。

2
投票

有一个关于它的公开问题here,所以自动覆盖过滤似乎是一项正在进行的工作。

编辑有一个pull request(接受)引入过滤生成的kotlin代码。它还没有找到它进入发布的方式。但到目前为止,人们已经在SNAPSHOT版本中测试了它,一切似乎都有效。

目前您最好的选择是使用SNAPSHOT版本。


1
投票

虽然它并没有真正回答你的问题,但你可以通过编写涵盖数据类生成的函数的测试来完全覆盖jacoco中的数据类。

例如,假设有一个数据类,其中包含一个var和一个val

data class MyDataClass(var s1: String, val s2: String)

当我运行jacoco时,我发现它正在测量MyDataClass生成的以下内容的覆盖范围:

  • hashCode()
  • equals(Object)
  • toString()
  • MyDataClass(String, String)
  • copy(String, String)
  • setS1(String)
  • getS1()
  • getS2()
  • component1()
  • component2()

涵盖大部分内容的单元测试可能是:

 @Test
 fun testCodeCoverageForMyDataClass() {
     // call the constructor
     val tested = MyDataClass("original s1", "original s2").apply {
         // call the setters
         s1 = "new s1"

         // call the getters
         assertEquals("new s1 original s2", "$s1 $s2")

         // call toString()
         assertEquals("MyDataClass(s1=new s1, s2=original s2)", "$this")

         // call componentN() functions
         val (res1, res2) = this
         assertEquals("new s1 original s2", "$res1 $res2")
    }

    // call copy()
    val testedCopy = tested.copy(s2 = "new s2").apply {
        // call equals()
        assertNotEquals(this, tested)

        // call hashCode()
        assertNotEquals(this.hashCode(), tested.hashCode())
    }
}

我知道,这是一种痛苦,但在有支持之前,这有助于我完成覆盖。


1
投票

如果您将数据类放在特定包或特定文件中,则可以将它们从classDirectories中排除。在下面的示例中,我将数据类放在**/model/**下:

task kotlinJacocoTestReport(type: JacocoReport, dependsOn: 'test') {

    reports {
        html.enabled = true
        html.destination = "${buildDir}/reports/jacoco"
    }

    sourceDirectories = files(["${project.projectDir}/src/main/kotlin"])
    classDirectories = fileTree(dir: "${buildDir}/classes/kotlin/main", excludes: ['**/model/**'])
    executionData = files("${buildDir}/jacoco/test.exec")
}

1
投票

使用以下文档中记录的插件:Kotlin plugin generated

该插件通过在幕后添加@lombok.Generated注释,从代码覆盖中删除所有合成的Kotlin生成的代码(自动获取器和设置器,并且应该干净地覆盖您的数据类)。

请注意,您必须使用Jacoco 0.8或更高版本才能工作。

© www.soinside.com 2019 - 2024. All rights reserved.