0

I am using the scoverage in Scala project. During the build, I generate coverage HTML and XML reports. I need to parse the XML file (i.e. scoverage.xml) to extract metrics for each class on: * lines coverage: number of covered ones vs total * statements coverage: number of covered ones vs total * branches coverage: number of covered ones vs total * functions coverage: number of covered ones vs total

Looking at the scoverage repo, I see that the report is generated by ScoverageXmlWriter.scala but it is not documented!!

So here is an example output of the statement tag:

<statement package="<package>" class="<class>" class-type="Object" full-class-name="<package>.<class>" source="/path/to/<package>/<class>.scala" method="compileScala" start="350" end="350" line="18" branch="false" invocation-count="1" ignored="false">
</statement>

What does the attribute means? Is line corresponding to the line number in the file? and what's start and end stands for?

bachr
  • 5,780
  • 12
  • 57
  • 92
  • 1
    I had the same questions a couple of years ago when writing [this](https://github.com/mwz/sonar-scala/blob/master/src/main/scala/com/mwz/sonar/scala/scoverage/ScoverageReportParser.scala). Maybe you will find that code easier to read / understand? – Luis Miguel Mejía Suárez May 06 '20 at 18:51
  • Nice, I will check it out. – bachr May 06 '20 at 18:58
  • @LuisMiguelMejíaSuárez do you know what's `statement-rate`? is it percentage of covered statements, i.e. if I multiply it by `statement-count` I get the count of covered statements? – bachr May 06 '20 at 19:02
  • 1
    According to my code, yeah it is the percentage of statements covered by your tests in that file. For the count of covered statements I used `statements-invoked` but I guess the multiplication should give a similar result. - In any case, remember I wrote that code more than 2 years ago, I hardly remember what it does. – Luis Miguel Mejía Suárez May 06 '20 at 19:08

1 Answers1

0

I found the answers in the sbt plugin code itself coverage.scala#L159-L168

  def invokedStatements: Iterable[Statement] = statements.filter(_.count > 0)
  def invokedStatementCount = invokedStatements.size
  def statementCoverage: Double = if (statementCount == 0) 1 else invokedStatementCount / statementCount.toDouble
  def statementCoveragePercent = statementCoverage * 100
  def statementCoverageFormatted: String = twoFractionDigits(statementCoveragePercent)
  def branches: Iterable[Statement] = statements.filter(_.branch)
  def branchCount: Int = branches.size
  def branchCoveragePercent = branchCoverage * 100
  def invokedBranches: Iterable[Statement] = branches.filter(_.count > 0)
  def invokedBranchesCount = invokedBranches.size

I simply had to parse the XML while considering the snippet above to recalculate the counts (e.g. branches count vs covered).

bachr
  • 5,780
  • 12
  • 57
  • 92