junit

package module
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 28, 2025 License: BSD-3-Clause Imports: 4 Imported by: 1

README

JUnit Report XML Generator for Go

This repository provides a Go package and a CLI application to generate JUnit XML reports compatible with GitLab CI (and other CI systems).

Go Package

The junit package allows you to programmatically create JUnit XML reports.

Installation
go get github.com/oktalz/junit-report
Usage
package main

import (
	"log"

	"github.com/oktalz/junit-report"
)

func main() {
	// Create a new report
	ts := junit.NewTestSuites()

	// Add a test suite
	suite := ts.AddSuite("My Suite")

	// Add a passing test case
	suite.AddMessageOK("main.go", "Build Check", "Build successful")

	// Add an error test case
	suite.AddMessageError("main.go", "Build Check", "Build failed")

	// Add a failing test case
	suite.AddMessageFailed("linter.go", "Lint Check", "Linting failed: variable unused")

	// Write to file
	if err := ts.Write("report.xml"); err != nil {
		log.Fatal(err)
	}
}

You can also load an existing report and append to it:

ts, err := junit.Load("report.xml")
if err != nil {
    // Handle error (e.g., create new if not found)
    ts = junit.NewTestSuites()
}

suite := ts.GetOrCreateSuite("My Suite")
suite.AddMessageOK("test.go", "New Test", "Passed")

ts.Write("report.xml")

CLI Application

The junit-report CLI allows you to add test results to a JUnit XML file from the command line. This is useful for scripts and CI pipelines.

Installation
go install github.com/oktalz/junit-report/cmd/junit-report@latest
Usage

The add subcommand is used to add a test case result.

Arguments
  • --output: Path to the output XML file. Can also be set via JUNIT_FILE environment variable.
  • --status: Status of the check (ok, error or failed). Default: ok.
  • --file: File path related to the check.
  • --message: Name/Message for the check.
  • --description: Detailed description or output.
  • --suite: Name of the test suite. Default: General.
Examples

Add a passing check:

junit-report add --output=report.xml --status=ok --file=main.go --message="Build" --description="Build successful"

Add an error check:

junit-report add --output=report.xml --status=error --file=main.go --message="Build" --description="Build failed"

Add a failing check:

junit-report add --output=report.xml --status=failed --file=linter.go --message="Linter" --description="Found 5 lint errors"

Using Environment Variable:

export JUNIT_FILE=report.xml
junit-report add --status=ok --message="Env Test"

Appending to existing file:

If the output file exists, the tool will load it and append the new test case to the specified suite (creating the suite if it doesn't exist).

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Error

type Error struct {
	Message string `xml:"message,attr,omitempty"`
	Type    string `xml:"type,attr,omitempty"`
	Content string `xml:",chardata"`
}

Error represents an errored test case.

type Failure

type Failure struct {
	Message string `xml:"message,attr,omitempty"`
	Type    string `xml:"type,attr,omitempty"`
	Content string `xml:",chardata"`
}

Failure represents a failed test case.

type Skipped

type Skipped struct {
	Message string `xml:"message,attr,omitempty"`
}

Skipped represents a skipped test case.

type SystemErr

type SystemErr struct {
	Content string `xml:",chardata"`
}

SystemErr represents standard error.

type SystemOut

type SystemOut struct {
	Content string `xml:",chardata"`
}

SystemOut represents standard output.

type TestCase

type TestCase struct {
	XMLName   xml.Name   `xml:"testcase"`
	Name      string     `xml:"name,attr"`
	ClassName string     `xml:"classname,attr"`
	File      string     `xml:"file,attr,omitempty"`
	Time      string     `xml:"time,attr,omitempty"`
	Failure   *Failure   `xml:"failure,omitempty"`
	Error     *Error     `xml:"error,omitempty"`
	Skipped   *Skipped   `xml:"skipped,omitempty"`
	SystemOut *SystemOut `xml:"system-out,omitempty"`
	SystemErr *SystemErr `xml:"system-err,omitempty"`
}

TestCase represents a single test case.

func (*TestCase) Errored

func (tc *TestCase) Errored(message, errorType, content string)

Errored marks the test case as errored.

func (*TestCase) Failed

func (tc *TestCase) Failed(message, failureType, content string)

Failed marks the test case as failed.

func (*TestCase) SetFile

func (tc *TestCase) SetFile(file string)

SetFile sets the file path for the test case.

func (*TestCase) SetSystemErr

func (tc *TestCase) SetSystemErr(content string)

SetSystemErr sets the system-err content.

func (*TestCase) SetSystemOut

func (tc *TestCase) SetSystemOut(content string)

SetSystemOut sets the system-out content.

func (*TestCase) SetTime

func (tc *TestCase) SetTime(duration string)

SetTime sets the execution time for the test case.

func (*TestCase) Skip

func (tc *TestCase) Skip(message string)

Skipped marks the test case as skipped.

type TestSuite

type TestSuite struct {
	XMLName   xml.Name    `xml:"testsuite"`
	Name      string      `xml:"name,attr"`
	Tests     int         `xml:"tests,attr"`
	Failures  int         `xml:"failures,attr"`
	Errors    int         `xml:"errors,attr"`
	Time      string      `xml:"time,attr,omitempty"`
	Timestamp string      `xml:"timestamp,attr,omitempty"`
	TestCases []*TestCase `xml:"testcase"`
}

TestSuite represents a test suite.

func (*TestSuite) AddMessageError

func (ts *TestSuite) AddMessageError(file, message, description string)

AddMessageError adds an errored test case with a message and description. If a test case with the same file and message exists, it updates it to errored.

func (*TestSuite) AddMessageFailed

func (ts *TestSuite) AddMessageFailed(file, message, description string)

AddMessageFailed adds a failing test case with a message and description. If a test case with the same file and message already exists, it updates it to failed.

func (*TestSuite) AddMessageOK

func (ts *TestSuite) AddMessageOK(file, message, description string)

AddMessageOK adds a passing test case with a message and description. If a test case with the same file and message already exists, it does nothing.

func (*TestSuite) AddTestCase

func (ts *TestSuite) AddTestCase(name, classname string) *TestCase

AddTestCase adds a new test case to the suite.

func (*TestSuite) UpdateCounts

func (ts *TestSuite) UpdateCounts()

UpdateCounts updates the failure and error counts for the suite. This should be called before marshaling if counts are not manually managed.

type TestSuites

type TestSuites struct {
	XMLName    xml.Name     `xml:"testsuites"`
	TestSuites []*TestSuite `xml:"testsuite"`
}

TestSuites is the root element of the JUnit XML report.

func Load

func Load(fileName string) (*TestSuites, error)

Load loads the XML report from a file.

func NewTestSuites

func NewTestSuites() *TestSuites

NewTestSuites creates a new TestSuites object.

func (*TestSuites) AddSuite

func (ts *TestSuites) AddSuite(name string) *TestSuite

AddSuite adds a new test suite to the report.

func (*TestSuites) GetOrCreateSuite

func (ts *TestSuites) GetOrCreateSuite(name string) *TestSuite

GetOrCreateSuite returns an existing suite by name or creates a new one.

func (*TestSuites) Marshal

func (ts *TestSuites) Marshal() ([]byte, error)

Marshal returns the XML encoding of the TestSuites.

func (*TestSuites) String

func (ts *TestSuites) String() string

func (*TestSuites) UpdateCounts

func (ts *TestSuites) UpdateCounts()

UpdateCounts updates the counts for all suites.

func (*TestSuites) Write

func (ts *TestSuites) Write(fileName string) error

Write writes the XML report to a file. If fileName is empty, it checks the JUNIT_FILE environment variable.

Directories

Path Synopsis
cmd
junit-report command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL