CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-scoverage--scalac-scoverage-plugin

Comprehensive code coverage tool for Scala providing statement and branch coverage through compiler plugin instrumentation and report generation

Pending
Overview
Eval results
Files

cobertura-reports.mddocs/

Cobertura XML Reports

The CoberturaXmlWriter generates Cobertura-compatible XML reports for integration with build systems, CI/CD pipelines, and coverage analysis tools that expect the standard Cobertura format. This enables seamless integration with tools like Jenkins, SonarQube, and other coverage analysis platforms.

Core API

CoberturaXmlWriter Class

class CoberturaXmlWriter(
  sourceDirectories: Seq[File],
  outputDir: File,
  sourceEncoding: Option[String]
) extends BaseReportWriter(sourceDirectories, outputDir, sourceEncoding) {
  def write(coverage: Coverage): Unit
}

Constructor Parameters:

  • sourceDirectories: Sequence of source directories for relative path calculation
  • outputDir: Directory where the cobertura.xml file will be generated
  • sourceEncoding: Optional character encoding for reading source files

Methods:

  • write(coverage: Coverage): Unit - Generates cobertura.xml file

Alternative Constructor

// Single base directory constructor
class CoberturaXmlWriter(
  baseDir: File,
  outputDir: File, 
  sourceEncoding: Option[String]
)

Usage Examples

Basic Cobertura Report Generation

import java.io.File
import scoverage.reporter.CoberturaXmlWriter
import scoverage.domain.Coverage

val sourceDirectories = Seq(new File("src/main/scala"))
val outputDir = new File("target/scoverage-report")
val writer = new CoberturaXmlWriter(sourceDirectories, outputDir, Some("UTF-8"))

val coverage: Coverage = loadCoverageData()
writer.write(coverage)
// Generates target/scoverage-report/cobertura.xml

CI/CD Pipeline Integration

import java.io.File
import scoverage.reporter.CoberturaXmlWriter

// Generate Cobertura report for Jenkins/SonarQube integration
val sourceDirectories = Seq(
  new File("module1/src/main/scala"),
  new File("module2/src/main/scala")
)
val outputDir = new File(sys.env.getOrElse("BUILD_DIR", "target") + "/coverage-reports")
val writer = new CoberturaXmlWriter(sourceDirectories, outputDir, Some("UTF-8"))

val coverage: Coverage = aggregateMultiModuleCoverage()
writer.write(coverage)

// The cobertura.xml can now be consumed by CI tools
println(s"Cobertura report generated at: ${outputDir}/cobertura.xml")

Multi-Project Build Integration

// Aggregate coverage from multiple projects
val allSourceDirs = Seq(
  new File("project-a/src/main/scala"),
  new File("project-b/src/main/scala"),
  new File("shared/src/main/scala")
)

val coberturaWriter = new CoberturaXmlWriter(
  allSourceDirs,
  new File("target/aggregated-coverage"),
  Some("UTF-8")
)

val aggregatedCoverage = CoverageAggregator.aggregatedCoverage(dataDirs, sourceRoot)
coberturaWriter.write(aggregatedCoverage)

Generated XML Structure

The Cobertura XML format follows the standard Cobertura DTD structure:

<?xml version="1.0"?>
<!DOCTYPE coverage SYSTEM "https://cobertura.sourceforge.net/xml/coverage-04.dtd">
<coverage line-rate="0.85"
          lines-valid="1000"
          lines-covered="850"
          branches-valid="200"
          branches-covered="160"
          branch-rate="0.80"
          complexity="0"
          version="1.0"
          timestamp="1609459200000">
  <sources>
    <source>--source</source>
    <source>/path/to/src/main/scala</source>
  </sources>
  <packages>
    <package name="com.example.myapp"
             line-rate="0.90"
             branch-rate="0.85"
             complexity="0">
      <classes>
        <class name="com.example.myapp.MyClass"
               filename="MyClass.scala"
               line-rate="0.92"
               branch-rate="0.88"
               complexity="0">
          <methods>
            <method name="myMethod"
                    signature="()V"
                    line-rate="0.95"
                    branch-rate="0.90"
                    complexity="0">
              <lines>
                <line number="10" hits="5" branch="false"/>
                <line number="15" hits="3" branch="true"/>
              </lines>
            </method>
          </methods>
          <lines>
            <line number="10" hits="5" branch="false"/>
            <line number="15" hits="3" branch="true"/>
            <line number="20" hits="0" branch="false"/>
          </lines>
        </class>
      </classes>
    </package>
  </packages>
</coverage>

Cobertura Format Details

Root Coverage Element

  • line-rate: Overall line coverage as decimal (0.0 to 1.0)
  • lines-valid: Total number of executable lines
  • lines-covered: Number of lines that were executed
  • branches-valid: Total number of branch points
  • branches-covered: Number of branches that were executed
  • branch-rate: Overall branch coverage as decimal (0.0 to 1.0)
  • complexity: Cyclomatic complexity (always 0 in scoverage)
  • version: Report format version
  • timestamp: Generation time in milliseconds

Sources Section

Lists all source directories included in the coverage analysis:

  • --source: Marker indicating source directories follow
  • Individual <source> elements for each source directory path

Package Elements

  • name: Package name (fully qualified)
  • line-rate: Package-level line coverage rate (0.0 to 1.0)
  • branch-rate: Package-level branch coverage rate (0.0 to 1.0)
  • complexity: Always 0 in scoverage reports

Class Elements

  • name: Fully qualified class name
  • filename: Relative path to source file
  • line-rate: Class-level line coverage rate (0.0 to 1.0)
  • branch-rate: Class-level branch coverage rate (0.0 to 1.0)
  • complexity: Always 0 in scoverage reports

Method Elements

  • name: Method name
  • signature: Method signature (simplified to "()V" in scoverage)
  • line-rate: Method-level line coverage rate (0.0 to 1.0)
  • branch-rate: Method-level branch coverage rate (0.0 to 1.0)
  • complexity: Always 0 in scoverage reports

Line Elements

  • number: Line number in source file
  • hits: Number of times line was executed (0 means not covered)
  • branch: Whether line contains branch logic (true/false)

Output File

File Name and Location

The report is always generated as cobertura.xml in the specified output directory.

File Structure

The XML file includes:

  • XML declaration with UTF-8 encoding
  • DOCTYPE declaration referencing Cobertura DTD
  • Complete coverage hierarchy from packages down to individual lines

Tool Integration

Jenkins Integration

// Generate report for Jenkins Cobertura plugin
val writer = new CoberturaXmlWriter(sourceDirectories, new File("target/site/cobertura"), None)
writer.write(coverage)
// Configure Jenkins to read target/site/cobertura/cobertura.xml

SonarQube Integration

// Generate for SonarQube analysis
val sonarReportDir = new File("target/sonar-reports")
sonarReportDir.mkdirs()
val writer = new CoberturaXmlWriter(sourceDirectories, sonarReportDir, Some("UTF-8"))
writer.write(coverage)
// Configure sonar.scala.coverage.reportPaths=target/sonar-reports/cobertura.xml

Gradle Integration

// Generate Cobertura report in Gradle build
val sourceArray: Array[File] = sourceDirectories.toArray
val writer = new CoberturaXmlWriter(sourceArray, outputDir, encoding)
writer.write(coverage)

Differences from Scoverage XML

The Cobertura format differs from the native scoverage XML format:

  1. Decimal Rates: Uses 0.0-1.0 decimal format instead of percentages
  2. Line-Based: Focuses on line coverage rather than statement coverage
  3. Simplified Signatures: Method signatures are simplified to "()V"
  4. DTD Compliance: Strictly follows Cobertura DTD structure
  5. Complexity: Always reports complexity as 0 (not calculated by scoverage)

Error Handling

Common Issues:

  • IOException: File writing permissions or disk space problems
  • RuntimeException: Source directory path resolution failures
  • IllegalStateException: Invalid coverage data structure

Best Practices:

  • Ensure output directory exists and is writable
  • Verify source directories are accessible for canonical path resolution
  • Test with target CI/coverage tools to ensure compatibility
  • Monitor file size for large projects (Cobertura XML can be substantial)

Install with Tessl CLI

npx tessl i tessl/maven-org-scoverage--scalac-scoverage-plugin

docs

aggregation.md

cobertura-reports.md

coverage-model.md

html-reports.md

index.md

io-utils.md

plugin.md

runtime.md

serialization.md

xml-reports.md

tile.json