Code Monkey home page Code Monkey logo

go-junit's Introduction

License Actions Go Report Card Go Dev Releases

Go JUnit

๐Ÿœ Go library for ingesting JUnit XML reports

Installing

You can fetch this library by running the following

go get -u github.com/joshdk/go-junit

Usage

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

suites, err := junit.Ingest(xml)

You can then inspect the contents of the ingested suites.

for _, suite := range suites {
    fmt.Println(suite.Name)
    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.

JUnitXmlReporter.constructor
  should default path to an empty string
    failed: Assertion failed
  should default consolidate to true
    skipped
  should default useDotNotation to true
    passed

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{
    "test-reports/report-1.xml",
    "test-reports/report-2.xml",
})

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.

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

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

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

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

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

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

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

Contributing

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.

License

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

Created by Josh Komoroske โ˜•

go-junit's People

Contributors

arjunpur avatar ekharchenko-avito avatar fkorotkov avatar gaborszakacs avatar joshdk avatar rwbergstrom avatar tadam313 avatar vistaarjuneja avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

go-junit's Issues

Allow reading a message from failure tag

Consider following example. Currently there is no way to read CDATA from <failure>...</failure> tag.

	<testsuite name="github.com/stackrox/rox/central/resourcecollection/datastore/store/postgres" tests="1" failures="1" errors="0" id="78" hostname="merge-go-postgres-tests-stackrox-initial" time="2.751" timestamp="2022-10-11T13:32:27Z">
		<properties>
			<property name="coverage.statements.pct" value="49.00"></property>
		</properties>
		<testcase name="TestCollectionsStore" classname="github.com/stackrox/rox/central/resourcecollection/datastore/store/postgres" time="2.330">
			<failure message="Failed"><![CDATA[    env_isolator.go:41: EnvIsolator: Setting ROX_POSTGRES_DATASTORE to true]]></failure>
		</testcase>
	</testsuite>

Expose suite timestamp

Many junit files (including readme example) have timestamp. It will be nice if this timestamp be available in suite structure.

<testsuite name="JUnitXmlReporter.constructor" timestamp="2013-05-24T10:23:58">

Use time in suite if provided

I have a junit xml like this:

<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="client" tests="72" failures="0" errors="0" time="2.176">
  <testsuite name="src/__tests__/1.test.ts" errors="0" failures="0" skipped="0" timestamp="2023-03-01T22:51:14" time="1.56" tests="7">
    <testcase classname="1 hook" name="should set a" time="0.029">
    </testcase>
    <testcase classname="1 hook" name="should set b" time="0.006">
    </testcase>
    <testcase classname="1 hook" name="should set c" time="0.005">
    </testcase>
    <testcase classname="1 hook" name="should set d" time="0.004">
    </testcase>
    <testcase classname="1 hook" name="should set e" time="0.007">
    </testcase>
    <testcase classname="1 hook" name="should set f" time="0.003">
    </testcase>
    <testcase classname="1 hook" name="should set g" time="0.01">
    </testcase>
  </testsuite>
  <testsuite name="src/__tests__/2.test.tsx" errors="0" failures="0" skipped="0" timestamp="2023-03-01T22:51:14" time="1.623" tests="6">
    <testcase classname="2" name="should set a" time="0.051">
    </testcase>
    <testcase classname="2" name="should set b" time="0.005">
    </testcase>
    <testcase classname="2" name="should set c" time="0.009">
    </testcase>
    <testcase classname="2" name="should set d" time="0.014">
    </testcase>
    <testcase classname="2" name="should set e" time="0.015">
    </testcase>
    <testcase classname="2" name="should set f" time="0.004">
    </testcase>
  </testsuite>
</testsuites>

(this is from the output of https://www.npmjs.com/package/jest-junit)

Expected

I expect the suites' totals.duration to match the time mentioned in the testsuite itself rather than be the sum of times in testcases.

Actual

The totals.duration is the sum of the testcases. This leaves out the time spent by the testsuite in setup and teardown which is not part of any 1 individual test case.

Expose skipped message

The Junit schema allows results to present a message as a child of a skipped element. It would be useful to be able to access that through go-junit. An example is below:

<testsuites>
    <testsuite tests="1" failures="0" time="" name="demo">
        <testcase classname="demo.case" name="test">
            <skipped message="reason"></skipped>
        </testcase>
    </testsuite>
</testsuites>

The source for this is line 335 of http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java

JUnit XML examples in the wild

Given the inconsistent and the property-based nature of the JUnit "spec", it is often the case where tests/suites may be rendered much differently by one tool or another.

If you have a novel JUnit XML file (especially if go-junit fails to parse it completely/sufficiently) please post it here (but anonymize its contents first).


Please include some brief information like:

  • Name of the tool that generated the XML file.
  • A link to its homepage.
  • A link, gist, or code block of the XML file.
  • Any notes on parsing errors, or missing information.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.