0
# Cobertura XML Reports
1
2
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.
3
4
## Core API
5
6
### CoberturaXmlWriter Class
7
8
```scala { .api }
9
class CoberturaXmlWriter(
10
sourceDirectories: Seq[File],
11
outputDir: File,
12
sourceEncoding: Option[String]
13
) extends BaseReportWriter(sourceDirectories, outputDir, sourceEncoding) {
14
def write(coverage: Coverage): Unit
15
}
16
```
17
18
**Constructor Parameters:**
19
- `sourceDirectories`: Sequence of source directories for relative path calculation
20
- `outputDir`: Directory where the cobertura.xml file will be generated
21
- `sourceEncoding`: Optional character encoding for reading source files
22
23
**Methods:**
24
- `write(coverage: Coverage): Unit` - Generates cobertura.xml file
25
26
### Alternative Constructor
27
28
```scala { .api }
29
// Single base directory constructor
30
class CoberturaXmlWriter(
31
baseDir: File,
32
outputDir: File,
33
sourceEncoding: Option[String]
34
)
35
```
36
37
## Usage Examples
38
39
### Basic Cobertura Report Generation
40
41
```scala
42
import java.io.File
43
import scoverage.reporter.CoberturaXmlWriter
44
import scoverage.domain.Coverage
45
46
val sourceDirectories = Seq(new File("src/main/scala"))
47
val outputDir = new File("target/scoverage-report")
48
val writer = new CoberturaXmlWriter(sourceDirectories, outputDir, Some("UTF-8"))
49
50
val coverage: Coverage = loadCoverageData()
51
writer.write(coverage)
52
// Generates target/scoverage-report/cobertura.xml
53
```
54
55
### CI/CD Pipeline Integration
56
57
```scala
58
import java.io.File
59
import scoverage.reporter.CoberturaXmlWriter
60
61
// Generate Cobertura report for Jenkins/SonarQube integration
62
val sourceDirectories = Seq(
63
new File("module1/src/main/scala"),
64
new File("module2/src/main/scala")
65
)
66
val outputDir = new File(sys.env.getOrElse("BUILD_DIR", "target") + "/coverage-reports")
67
val writer = new CoberturaXmlWriter(sourceDirectories, outputDir, Some("UTF-8"))
68
69
val coverage: Coverage = aggregateMultiModuleCoverage()
70
writer.write(coverage)
71
72
// The cobertura.xml can now be consumed by CI tools
73
println(s"Cobertura report generated at: ${outputDir}/cobertura.xml")
74
```
75
76
### Multi-Project Build Integration
77
78
```scala
79
// Aggregate coverage from multiple projects
80
val allSourceDirs = Seq(
81
new File("project-a/src/main/scala"),
82
new File("project-b/src/main/scala"),
83
new File("shared/src/main/scala")
84
)
85
86
val coberturaWriter = new CoberturaXmlWriter(
87
allSourceDirs,
88
new File("target/aggregated-coverage"),
89
Some("UTF-8")
90
)
91
92
val aggregatedCoverage = CoverageAggregator.aggregatedCoverage(dataDirs, sourceRoot)
93
coberturaWriter.write(aggregatedCoverage)
94
```
95
96
## Generated XML Structure
97
98
The Cobertura XML format follows the standard Cobertura DTD structure:
99
100
```xml
101
<?xml version="1.0"?>
102
<!DOCTYPE coverage SYSTEM "https://cobertura.sourceforge.net/xml/coverage-04.dtd">
103
<coverage line-rate="0.85"
104
lines-valid="1000"
105
lines-covered="850"
106
branches-valid="200"
107
branches-covered="160"
108
branch-rate="0.80"
109
complexity="0"
110
version="1.0"
111
timestamp="1609459200000">
112
<sources>
113
<source>--source</source>
114
<source>/path/to/src/main/scala</source>
115
</sources>
116
<packages>
117
<package name="com.example.myapp"
118
line-rate="0.90"
119
branch-rate="0.85"
120
complexity="0">
121
<classes>
122
<class name="com.example.myapp.MyClass"
123
filename="MyClass.scala"
124
line-rate="0.92"
125
branch-rate="0.88"
126
complexity="0">
127
<methods>
128
<method name="myMethod"
129
signature="()V"
130
line-rate="0.95"
131
branch-rate="0.90"
132
complexity="0">
133
<lines>
134
<line number="10" hits="5" branch="false"/>
135
<line number="15" hits="3" branch="true"/>
136
</lines>
137
</method>
138
</methods>
139
<lines>
140
<line number="10" hits="5" branch="false"/>
141
<line number="15" hits="3" branch="true"/>
142
<line number="20" hits="0" branch="false"/>
143
</lines>
144
</class>
145
</classes>
146
</package>
147
</packages>
148
</coverage>
149
```
150
151
## Cobertura Format Details
152
153
### Root Coverage Element
154
- `line-rate`: Overall line coverage as decimal (0.0 to 1.0)
155
- `lines-valid`: Total number of executable lines
156
- `lines-covered`: Number of lines that were executed
157
- `branches-valid`: Total number of branch points
158
- `branches-covered`: Number of branches that were executed
159
- `branch-rate`: Overall branch coverage as decimal (0.0 to 1.0)
160
- `complexity`: Cyclomatic complexity (always 0 in scoverage)
161
- `version`: Report format version
162
- `timestamp`: Generation time in milliseconds
163
164
### Sources Section
165
Lists all source directories included in the coverage analysis:
166
- `--source`: Marker indicating source directories follow
167
- Individual `<source>` elements for each source directory path
168
169
### Package Elements
170
- `name`: Package name (fully qualified)
171
- `line-rate`: Package-level line coverage rate (0.0 to 1.0)
172
- `branch-rate`: Package-level branch coverage rate (0.0 to 1.0)
173
- `complexity`: Always 0 in scoverage reports
174
175
### Class Elements
176
- `name`: Fully qualified class name
177
- `filename`: Relative path to source file
178
- `line-rate`: Class-level line coverage rate (0.0 to 1.0)
179
- `branch-rate`: Class-level branch coverage rate (0.0 to 1.0)
180
- `complexity`: Always 0 in scoverage reports
181
182
### Method Elements
183
- `name`: Method name
184
- `signature`: Method signature (simplified to "()V" in scoverage)
185
- `line-rate`: Method-level line coverage rate (0.0 to 1.0)
186
- `branch-rate`: Method-level branch coverage rate (0.0 to 1.0)
187
- `complexity`: Always 0 in scoverage reports
188
189
### Line Elements
190
- `number`: Line number in source file
191
- `hits`: Number of times line was executed (0 means not covered)
192
- `branch`: Whether line contains branch logic (true/false)
193
194
## Output File
195
196
### File Name and Location
197
The report is always generated as `cobertura.xml` in the specified output directory.
198
199
### File Structure
200
The XML file includes:
201
- XML declaration with UTF-8 encoding
202
- DOCTYPE declaration referencing Cobertura DTD
203
- Complete coverage hierarchy from packages down to individual lines
204
205
## Tool Integration
206
207
### Jenkins Integration
208
```scala
209
// Generate report for Jenkins Cobertura plugin
210
val writer = new CoberturaXmlWriter(sourceDirectories, new File("target/site/cobertura"), None)
211
writer.write(coverage)
212
// Configure Jenkins to read target/site/cobertura/cobertura.xml
213
```
214
215
### SonarQube Integration
216
```scala
217
// Generate for SonarQube analysis
218
val sonarReportDir = new File("target/sonar-reports")
219
sonarReportDir.mkdirs()
220
val writer = new CoberturaXmlWriter(sourceDirectories, sonarReportDir, Some("UTF-8"))
221
writer.write(coverage)
222
// Configure sonar.scala.coverage.reportPaths=target/sonar-reports/cobertura.xml
223
```
224
225
### Gradle Integration
226
```scala
227
// Generate Cobertura report in Gradle build
228
val sourceArray: Array[File] = sourceDirectories.toArray
229
val writer = new CoberturaXmlWriter(sourceArray, outputDir, encoding)
230
writer.write(coverage)
231
```
232
233
## Differences from Scoverage XML
234
235
The Cobertura format differs from the native scoverage XML format:
236
237
1. **Decimal Rates**: Uses 0.0-1.0 decimal format instead of percentages
238
2. **Line-Based**: Focuses on line coverage rather than statement coverage
239
3. **Simplified Signatures**: Method signatures are simplified to "()V"
240
4. **DTD Compliance**: Strictly follows Cobertura DTD structure
241
5. **Complexity**: Always reports complexity as 0 (not calculated by scoverage)
242
243
## Error Handling
244
245
**Common Issues:**
246
- `IOException`: File writing permissions or disk space problems
247
- `RuntimeException`: Source directory path resolution failures
248
- `IllegalStateException`: Invalid coverage data structure
249
250
**Best Practices:**
251
- Ensure output directory exists and is writable
252
- Verify source directories are accessible for canonical path resolution
253
- Test with target CI/coverage tools to ensure compatibility
254
- Monitor file size for large projects (Cobertura XML can be substantial)