...
1[![License][license-badge]][license-link]
2[![Godoc][godoc-badge]][godoc-link]
3[![Go Report Card][go-report-badge]][go-report-link]
4[![CircleCI][circleci-badge]][circleci-link]
5
6# Go JUnit
7
8🐜 Go library for ingesting JUnit XML reports
9
10## Installing
11
12You can fetch this library by running the following
13
14```bash
15go get -u github.com/joshdk/go-junit
16```
17
18## Usage
19
20### Data Ingestion
21
22This library has a number of ingestion methods for convenience.
23
24The simplest of which parses raw JUnit XML data.
25
26```go
27xml := []byte(`
28 <?xml version="1.0" encoding="UTF-8"?>
29 <testsuites>
30 <testsuite name="JUnitXmlReporter" errors="0" tests="0" failures="0" time="0" timestamp="2013-05-24T10:23:58" />
31 <testsuite name="JUnitXmlReporter.constructor" errors="0" skipped="1" tests="3" failures="1" time="0.006" timestamp="2013-05-24T10:23:58">
32 <properties>
33 <property name="java.vendor" value="Sun Microsystems Inc." />
34 <property name="compiler.debug" value="on" />
35 <property name="project.jdk.classpath" value="jdk.classpath.1.6" />
36 </properties>
37 <testcase classname="JUnitXmlReporter.constructor" name="should default path to an empty string" time="0.006">
38 <failure message="test failure">Assertion failed</failure>
39 </testcase>
40 <testcase classname="JUnitXmlReporter.constructor" name="should default consolidate to true" time="0">
41 <skipped />
42 </testcase>
43 <testcase classname="JUnitXmlReporter.constructor" name="should default useDotNotation to true" time="0" />
44 </testsuite>
45 </testsuites>
46`)
47
48suites, err := junit.Ingest(xml)
49if err != nil {
50 log.Fatalf("failed to ingest JUnit xml %v", err)
51}
52```
53
54You can then inspect the contents of the ingested suites.
55
56```go
57for _, suite := range suites {
58 fmt.Println(suite.Name)
59 for _, test := range suite.Tests {
60 fmt.Printf(" %s\n", test.Name)
61 if test.Error != nil {
62 fmt.Printf(" %s: %s\n", test.Status, test.Error.Error())
63 } else {
64 fmt.Printf(" %s\n", test.Status)
65 }
66 }
67}
68```
69
70And observe some output like this.
71
72```
73JUnitXmlReporter
74JUnitXmlReporter.constructor
75 should default path to an empty string
76 failed: Assertion failed
77 should default consolidate to true
78 skipped
79 should default useDotNotation to true
80 passed
81```
82
83### More Examples
84
85Additionally, you can ingest an entire file.
86
87```go
88suites, err := junit.IngestFile("test-reports/report.xml")
89if err != nil {
90 log.Fatalf("failed to ingest JUnit xml %v", err)
91}
92```
93
94Or a list of multiple files.
95
96```go
97suites, err := junit.IngestFiles([]string{
98 "test-reports/report-1.xml",
99 "test-reports/report-2.xml",
100})
101if err != nil {
102 log.Fatalf("failed to ingest JUnit xml %v", err)
103}
104```
105
106Or any `.xml` files inside of a directory.
107
108```go
109suites, err := junit.IngestDir("test-reports/")
110if err != nil {
111 log.Fatalf("failed to ingest JUnit xml %v", err)
112}
113```
114
115### Data Formats
116
117Due to the lack of implementation consistency in software that generates JUnit XML files, this library needs to take a somewhat looser approach to ingestion. As a consequence, many different possible JUnit formats can easily be ingested.
118
119A single top level `testsuite` tag, containing multiple `testcase` instances.
120
121```xml
122<testsuite>
123 <testcase name="Test case 1" />
124 <testcase name="Test case 2" />
125</testsuite>
126```
127
128A single top level `testsuites` tag, containing multiple `testsuite` instances.
129
130```xml
131<testsuites>
132 <testsuite>
133 <testcase name="Test case 1" />
134 <testcase name="Test case 2" />
135 </testsuite>
136</testsuites>
137```
138
139(Despite not technically being valid XML) Multiple top level `testsuite` tags, containing multiple `testcase` instances.
140
141```xml
142<testsuite>
143 <testcase name="Test case 1" />
144 <testcase name="Test case 2" />
145</testsuite>
146<testsuite>
147 <testcase name="Test case 3" />
148 <testcase name="Test case 4" />
149</testsuite>
150```
151
152In all cases, omitting (or even duplicated) the XML declaration tag is allowed.
153
154```xml
155<?xml version="1.0" encoding="UTF-8"?>
156```
157
158## Contributing
159
160Found a bug or want to make go-junit better? Please [open a pull request](https://github.com/joshdk/go-junit/compare)!
161
162To make things easier, try out the following:
163
164- Running `make test` will run the test suite to verify behavior.
165
166- Running `make lint` will format the code, and report any linting issues using [golangci/golangci-lint](https://github.com/golangci/golangci-lint).
167
168## License
169
170This code is distributed under the [MIT License][license-link], see [LICENSE.txt][license-file] for more information.
171
172[circleci-badge]: https://circleci.com/gh/joshdk/go-junit.svg?&style=shield
173[circleci-link]: https://circleci.com/gh/joshdk/go-junit/tree/master
174[go-report-badge]: https://goreportcard.com/badge/github.com/joshdk/go-junit
175[go-report-link]: https://goreportcard.com/report/github.com/joshdk/go-junit
176[godoc-badge]: https://godoc.org/github.com/joshdk/go-junit?status.svg
177[godoc-link]: https://godoc.org/github.com/joshdk/go-junit
178[license-badge]: https://img.shields.io/badge/license-MIT-green.svg
179[license-file]: https://github.com/joshdk/go-junit/blob/master/LICENSE.txt
180[license-link]: https://opensource.org/licenses/MIT
View as plain text