0
# XML Report Generation
1
2
The ScoverageXmlWriter generates structured XML coverage reports in the scoverage format for programmatic consumption, CI/CD integration, and archival purposes. The XML format provides complete coverage data including statement details, method information, and hierarchical package/class organization.
3
4
## Core API
5
6
### ScoverageXmlWriter Class
7
8
```scala { .api }
9
class ScoverageXmlWriter(
10
sourceDirectories: Seq[File],
11
outputDir: File,
12
debug: Boolean,
13
sourceEncoding: Option[String]
14
) extends BaseReportWriter(sourceDirectories, outputDir, sourceEncoding) {
15
def write(coverage: Coverage): Unit
16
}
17
```
18
19
**Constructor Parameters:**
20
- `sourceDirectories`: Sequence of source directories for relative path calculation
21
- `outputDir`: Directory where XML report will be generated
22
- `debug`: Whether to include debug information in the XML output
23
- `sourceEncoding`: Optional character encoding for reading source files
24
25
**Methods:**
26
- `write(coverage: Coverage): Unit` - Generates XML report file
27
28
### Alternative Constructor
29
30
```scala { .api }
31
// Single source directory constructor
32
class ScoverageXmlWriter(
33
sourceDir: File,
34
outputDir: File,
35
debug: Boolean,
36
sourceEncoding: Option[String]
37
)
38
```
39
40
## Usage Examples
41
42
### Basic XML Report Generation
43
44
```scala
45
import java.io.File
46
import scoverage.reporter.ScoverageXmlWriter
47
import scoverage.domain.Coverage
48
49
val sourceDirectories = Seq(new File("src/main/scala"))
50
val outputDir = new File("target/scoverage-report")
51
val debug = false
52
val writer = new ScoverageXmlWriter(sourceDirectories, outputDir, debug, Some("UTF-8"))
53
54
val coverage: Coverage = loadCoverageData()
55
writer.write(coverage)
56
```
57
58
### Debug Mode XML Generation
59
60
```scala
61
import java.io.File
62
import scoverage.reporter.ScoverageXmlWriter
63
64
// Debug mode includes additional statement details like symbol names and tree names
65
val writer = new ScoverageXmlWriter(
66
sourceDirectories = Seq(new File("src/main/scala")),
67
outputDir = new File("target/scoverage-report"),
68
debug = true,
69
sourceEncoding = Some("UTF-8")
70
)
71
72
val coverage: Coverage = loadCoverageData()
73
writer.write(coverage)
74
```
75
76
### CI/CD Integration Example
77
78
```scala
79
// Generate XML report for automated processing
80
val xmlWriter = new ScoverageXmlWriter(
81
sourceDirectories = projectSourceDirs,
82
outputDir = buildOutputDir,
83
debug = false, // Minimal output for CI processing
84
sourceEncoding = Some("UTF-8")
85
)
86
87
xmlWriter.write(coverage)
88
89
// The generated scoverage.xml can then be parsed by CI tools
90
val reportFile = new File(buildOutputDir, "scoverage.xml")
91
// Process with CI/coverage tools...
92
```
93
94
## Generated XML Structure
95
96
### Standard Mode Output
97
98
The XML report includes the following hierarchical structure:
99
100
```xml
101
<scoverage statement-count="1250"
102
statements-invoked="1100"
103
statement-rate="88.00"
104
branch-rate="82.50"
105
version="1.0"
106
timestamp="1609459200000">
107
<packages>
108
<package name="com.example.myapp"
109
statement-count="500"
110
statements-invoked="450"
111
statement-rate="90.00">
112
<classes>
113
<class name="com.example.myapp.MyClass"
114
filename="MyClass.scala"
115
statement-count="50"
116
statements-invoked="45"
117
statement-rate="90.00"
118
branch-rate="85.00">
119
<methods>
120
<method name="myMethod"
121
statement-count="10"
122
statements-invoked="9"
123
statement-rate="90.00"
124
branch-rate="80.00">
125
<statements>
126
<statement package="com.example.myapp"
127
class="MyClass"
128
class-type="Class"
129
full-class-name="com.example.myapp.MyClass"
130
source="MyClass.scala"
131
method="myMethod"
132
start="150"
133
end="175"
134
line="10"
135
branch="false"
136
invocation-count="5"
137
ignored="false"/>
138
</statements>
139
</method>
140
</methods>
141
</class>
142
</classes>
143
</package>
144
</packages>
145
</scoverage>
146
```
147
148
### Debug Mode Output
149
150
When `debug = true`, statements include additional debugging information:
151
152
```xml
153
<statement package="com.example.myapp"
154
class="MyClass"
155
class-type="Class"
156
full-class-name="com.example.myapp.MyClass"
157
source="MyClass.scala"
158
method="myMethod"
159
start="150"
160
end="175"
161
line="10"
162
symbol="scala.Predef.println"
163
tree="Apply"
164
branch="false"
165
invocation-count="5"
166
ignored="false">
167
println("Hello World")
168
</statement>
169
```
170
171
## Output Files
172
173
### File Naming
174
- **Standard mode**: `scoverage.xml`
175
- **Debug mode**: `scoverage-debug.xml`
176
177
### File Location
178
Reports are written to the specified `outputDir` directory.
179
180
## XML Schema Details
181
182
### Root Element Attributes
183
- `statement-count`: Total number of statements in the codebase
184
- `statements-invoked`: Number of statements that were executed
185
- `statement-rate`: Statement coverage percentage (formatted to 2 decimal places)
186
- `branch-rate`: Branch coverage percentage (formatted to 2 decimal places)
187
- `version`: Scoverage XML format version
188
- `timestamp`: Report generation timestamp (milliseconds since epoch)
189
190
### Package Element Attributes
191
- `name`: Package name (fully qualified)
192
- `statement-count`: Statements in this package
193
- `statements-invoked`: Invoked statements in this package
194
- `statement-rate`: Package-level statement coverage percentage
195
196
### Class Element Attributes
197
- `name`: Fully qualified class name
198
- `filename`: Relative path to source file
199
- `statement-count`: Statements in this class
200
- `statements-invoked`: Invoked statements in this class
201
- `statement-rate`: Class-level statement coverage percentage
202
- `branch-rate`: Class-level branch coverage percentage
203
204
### Method Element Attributes
205
- `name`: Method name with parameter signature
206
- `statement-count`: Statements in this method
207
- `statements-invoked`: Invoked statements in this method
208
- `statement-rate`: Method-level statement coverage percentage
209
- `branch-rate`: Method-level branch coverage percentage
210
211
### Statement Element Attributes
212
- `package`: Package containing the statement
213
- `class`: Simple class name
214
- `class-type`: Type of class (Class, Object, or Trait)
215
- `full-class-name`: Fully qualified class name
216
- `source`: Relative path to source file
217
- `method`: Method containing the statement
218
- `start`: Character offset start position
219
- `end`: Character offset end position
220
- `line`: Line number in source file
221
- `branch`: Whether this statement represents a branch point
222
- `invocation-count`: Number of times statement was executed
223
- `ignored`: Whether statement was excluded from coverage
224
225
### Debug-Only Statement Attributes
226
- `symbol`: Scala symbol name (e.g., "scala.Predef.println")
227
- `tree`: Scala compiler tree type (e.g., "Apply", "Select")
228
229
## Integration with Build Tools
230
231
### SBT Integration
232
```scala
233
// Generate XML report after coverage collection
234
val coverage = loadCoverageData()
235
val xmlWriter = new ScoverageXmlWriter(
236
sourceDirectories = (Compile / scalaSource).value :: Nil,
237
outputDir = crossTarget.value,
238
debug = false,
239
sourceEncoding = Some("UTF-8")
240
)
241
xmlWriter.write(coverage)
242
```
243
244
### Gradle Integration
245
```scala
246
// Using Array constructor for Gradle compatibility
247
val sourceArray: Array[File] = sourceDirectories.toArray
248
val xmlWriter = new ScoverageXmlWriter(sourceArray, outputDir, debug, encoding)
249
xmlWriter.write(coverage)
250
```
251
252
## Error Handling
253
254
**Common Issues:**
255
- `IOException`: File writing permissions or disk space issues
256
- `RuntimeException`: Invalid source directory paths or canonical path resolution failures
257
- `IllegalArgumentException`: Invalid coverage data or missing statement information
258
259
**Best Practices:**
260
- Ensure output directory exists and is writable
261
- Verify all source directories are accessible
262
- Use debug mode only when needed as it increases file size significantly
263
- Consider XML file size for large codebases (debug mode can be very large)