Jacoco 正在分析 class 两次但失败了
Jacoco is analysing class twice and failing
我目前在我的 pom.xml:
中有 JaCoCo 的这个配置
<plugin>
<!-- Maven JaCoCo Plugin configuration for Code Coverage Report -->
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<excludes>
<exclude>**/*Test.class</exclude>
</excludes>
</configuration>
当我 运行 mvn clean verify site
时,我得到一个失败的构建,基于此警告(重要的是:我只有 1 个 class,SayHello.scala
):
Analyzed bundle 'dummy-project' with 2 classes
[WARNING] Rule violated for bundle dummy-project: classes missed count is 1, but expected maximum is 0
Failed to execute goal org.jacoco:jacoco-maven-plugin:0.8.5:check (default-check) on project dummy-project: Coverage checks have not been met. See log for details.
最后,当我检查报告时,它分析的是相同的 class(唯一的区别是第二行多了一个“.”),其中一个失败:
更新
SayHello.scala
package com.dummy
object SayHello {
def sayIt: String = "hello, world"
}
SayHelloTest.scala
package com.dummy
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers
class SayHelloTest extends AnyFunSuite with Matchers {
test("SayHello says hello") {
SayHello.sayIt shouldBe "hello, world"
}
}
有人遇到过类似的问题吗?谢谢。
JaCoCo 分析 .class
文件,而不是源文件。 Scala 编译器可以从单个源文件生成多个 .class
文件。您的 SayHello.scala
class 很可能包含同伴 object
。一个object
总是被编译成一个同名的class,最后是$
,它在字节码级别实现了伴生对象单例。如果您转到 target/classes
目录,您很可能会在那里看到这两个文件 - SayHello.class
和 SayHello$.class
.
JaCoCo 报告中的两条记录对应于那两个 class 文件。末尾的点而不是 $
很可能是 jacoco 报告呈现问题。
要跳过伴随对象 class 的分析,只需将其添加到您的排除列表中即可:
<configuration>
<excludes>
<exclude>**/*Test.class</exclude>
<exclude>**/*$.class</exclude>
</excludes>
</configuration>
但是,伴随对象中方法的覆盖似乎归因于 SayHello$.class
,而不是 SayHello.class
,因此通过从列表,你基本上失去了报道。
我不知道 Maven+JaCoCo 设置的任何解决方法,显然 jacoco-maven-plugin
并不是真正的 Scala 感知。然而,sbt 插件似乎已经解决了这些问题,参见例如https://blog.developer.atlassian.com/using-jacoco-a-code-coverage-tool-for-scala/
如果切换到 sbt 不是一个选项,您可以查看一些特定于 Scala 的代码覆盖工具,例如 scoverage, which also has a maven plugin。
我目前在我的 pom.xml:
中有 JaCoCo 的这个配置<plugin>
<!-- Maven JaCoCo Plugin configuration for Code Coverage Report -->
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<excludes>
<exclude>**/*Test.class</exclude>
</excludes>
</configuration>
当我 运行 mvn clean verify site
时,我得到一个失败的构建,基于此警告(重要的是:我只有 1 个 class,SayHello.scala
):
Analyzed bundle 'dummy-project' with 2 classes
[WARNING] Rule violated for bundle dummy-project: classes missed count is 1, but expected maximum is 0
Failed to execute goal org.jacoco:jacoco-maven-plugin:0.8.5:check (default-check) on project dummy-project: Coverage checks have not been met. See log for details.
最后,当我检查报告时,它分析的是相同的 class(唯一的区别是第二行多了一个“.”),其中一个失败:
更新
SayHello.scala
package com.dummy
object SayHello {
def sayIt: String = "hello, world"
}
SayHelloTest.scala
package com.dummy
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers
class SayHelloTest extends AnyFunSuite with Matchers {
test("SayHello says hello") {
SayHello.sayIt shouldBe "hello, world"
}
}
有人遇到过类似的问题吗?谢谢。
JaCoCo 分析 .class
文件,而不是源文件。 Scala 编译器可以从单个源文件生成多个 .class
文件。您的 SayHello.scala
class 很可能包含同伴 object
。一个object
总是被编译成一个同名的class,最后是$
,它在字节码级别实现了伴生对象单例。如果您转到 target/classes
目录,您很可能会在那里看到这两个文件 - SayHello.class
和 SayHello$.class
.
JaCoCo 报告中的两条记录对应于那两个 class 文件。末尾的点而不是 $
很可能是 jacoco 报告呈现问题。
要跳过伴随对象 class 的分析,只需将其添加到您的排除列表中即可:
<configuration>
<excludes>
<exclude>**/*Test.class</exclude>
<exclude>**/*$.class</exclude>
</excludes>
</configuration>
但是,伴随对象中方法的覆盖似乎归因于 SayHello$.class
,而不是 SayHello.class
,因此通过从列表,你基本上失去了报道。
我不知道 Maven+JaCoCo 设置的任何解决方法,显然 jacoco-maven-plugin
并不是真正的 Scala 感知。然而,sbt 插件似乎已经解决了这些问题,参见例如https://blog.developer.atlassian.com/using-jacoco-a-code-coverage-tool-for-scala/
如果切换到 sbt 不是一个选项,您可以查看一些特定于 Scala 的代码覆盖工具,例如 scoverage, which also has a maven plugin。