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

时间:2018-01-23 08:19:20

标签: unit-testing kotlin jacoco test-coverage

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

5 个答案:

答案 0 :(得分:3)

我一直在寻找针对相同测试覆盖率问题的解决方案,该解决方案具有针对数据模型类的自动生成的代码,偶然发现以下问题:
Kotlin + JaCoCo: Tuning Compiler to Skip Generated Code

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

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

  • 在生成报告时会滤除带有运行时可见和不可见注释(其简单名称为Generated)的类和方法(GitHub#731)。
  • 由Kotlin编译器添加的没有行号的方法会在生成报告时被滤除。 Nikolay Krasko(GitHub#689)的想法和实现。

答案 1 :(得分:2)

关于它here存在一个未解决的问题,因此自动覆盖过滤似乎正在进行中。

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

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

答案 2 :(得分: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())
    }
}

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

答案 3 :(得分: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")
}

答案 4 :(得分:1)

使用Kotlin plugin generated

中记录的插件

该插件通过在幕后添加@ lombok.Generated注释,从代码覆盖范围中删除了所有Kotlin合成的合成代码(自动getter和setter,并且应该清晰地覆盖数据类,无论它们在哪里)。

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