I currently have this configuration for JaCoCo in my pom.xml:
<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>
When I run mvn clean verify site
, I get a failed build, based in this warning (and important thing: I have only 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.
And finally, when I check the report, it's analysing the same class (the only difference is the extra "." in the second line), failing in one of them:
Update
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"
}
}
Anyone had a similar issue? Thank you.
JaCoCo analyzes .class
files, not source files. The Scala compiler may produce multiple .class
files from a single source file. Your SayHello.scala
class most likely contains a companion object
. An object
is always compiled to a class of the same name with $
at the end, which implements the companion object singleton at the bytecode level. If you go to your target/classes
directory, you'll most likely see those two files there - SayHello.class
and SayHello$.class
.
Two records in the JaCoCo report correspond to those two class files. The dot at the end instead of a $
is most likely a jacoco report rendering issue.
To skip the companion object class from analyzing, just add it to your exclusion list:
<configuration>
<excludes>
<exclude>**/*Test.class</exclude>
<exclude>**/*$.class</exclude>
</excludes>
</configuration>
However, it seems that coverage of the methods in the companion object is attributed to SayHello$.class
, not SayHello.class
, so by removing the $
class from the list, you essentially lose the coverage.
I'm not aware of any workarounds for the Maven+JaCoCo setup, apparently the jacoco-maven-plugin
is not really Scala-aware. However, the sbt plugin appears to have worked around these issues, see e.g. https://blog.developer.atlassian.com/using-jacoco-a-code-coverage-tool-for-scala/
If switching to sbt is not an option, you could take a look at some Scala-specific code coverage tools, like scoverage, which also has a maven plugin.