问题描述
我目前在我的 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 个类,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.
最后,当我检查报告时,它正在分析同一个类(唯一的区别是第二行中额外的“.”),其中之一失败了:
更新
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
类很可能包含一个同伴 object
。一个 object
总是被编译成一个以 $
结尾的同名类,它在字节码级别实现了伴生对象单例。如果您转到 target/classes
目录,您很可能会在那里看到这两个文件 - SayHello.class
和 SayHello$.class
。
JaCoCo 报告中的两条记录对应于这两个类文件。末尾的点而不是 $
很可能是 jacoco 报告呈现问题。
要跳过伴随对象类的分析,只需将其添加到您的排除列表中:
<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,它也有一个 maven plugin。