Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

License Actions Go Report Card Go Dev Releases

Go JUnit

🐜 Go library for ingesting JUnit XML reports


You can fetch this library by running the following

go get -u


Data Ingestion

This library has a number of ingestion methods for convenience.

The simplest of which parses raw JUnit XML data.

<?xml version="1.0" encoding="UTF-8"?>
    <testsuite name="JUnitXmlReporter.constructor" errors="0" skipped="1" tests="3" failures="1" time="0.006" timestamp="2013-05-24T10:23:58">
            <property name="java.vendor" value="Sun Microsystems Inc." />
            <property name="compiler.debug" value="on" />
            <property name="project.jdk.classpath" value="jdk.classpath.1.6" />
        <testcase classname="JUnitXmlReporter.constructor" name="should default path to an empty string" time="0.006">
            <failure message="test failure">Assertion failed</failure>
        <testcase classname="JUnitXmlReporter.constructor" name="should default consolidate to true" time="0">
            <skipped />
        <testcase classname="JUnitXmlReporter.constructor" name="should default useDotNotation to true" time="0" />
xml := []byte(`<?xml …`)

suites, err := junit.Ingest(xml)

You can then inspect the contents of the ingested suites.

for _, suite := range suites {
    for _, test := range suite.Tests {
        fmt.Printf("  %s\n", test.Name)
        if test.Error != nil {
            fmt.Printf("    %s: %v\n", test.Status, test.Error)
        } else {
            fmt.Printf("    %s\n", test.Status)

And observe some output like this.

  should default path to an empty string
    failed: Assertion failed
  should default consolidate to true
  should default useDotNotation to true

More Examples

Additionally, you can ingest an entire file.

suites, err := junit.IngestFile("test-reports/report.xml")

Or a list of multiple files.

suites, err := junit.IngestFiles([]string{

Or any .xml files inside of a directory.

suites, err := junit.IngestDir("test-reports/")

Data Formats

Due 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.

A single top level testsuite tag, containing multiple testcase instances.

    <testcase name="Test case 1" />
    <testcase name="Test case 2" />

A single top level testsuites tag, containing multiple testsuite instances.

        <testcase name="Test case 1" />
        <testcase name="Test case 2" />

(Despite not technically being valid XML) Multiple top level testsuite tags, containing multiple testcase instances.

    <testcase name="Test case 1" />
    <testcase name="Test case 2" />
    <testcase name="Test case 3" />
    <testcase name="Test case 4" />

In all cases, omitting (or even duplicated) the XML declaration tag is allowed.

<?xml version="1.0" encoding="UTF-8"?>


Found a bug or want to make go-junit better? Please open a pull request!

To make things easier, try out the following:

  • Running go test -v will run the test suite to verify behavior.

  • Running golangci-lint run will report any linting issues using golangci/golangci-lint.


This code is distributed under the MIT License, see LICENSE.txt for more information.

Created by Josh Komoroske β˜•