blob: d15d738b5deac2ade365be512be92e5954ee809f [file] [log] [blame]
package unittest
import (
"encoding/xml"
"io"
)
// JUnitTestSuites is a collection of JUnit test suites.
type JUnitTestSuites struct {
XMLName xml.Name `xml:"testsuites"`
Suites []JUnitTestSuite `xml:"testsuite"`
}
// JUnitTestSuite is a single JUnit test suite which may contain many
// testcases.
type JUnitTestSuite struct {
XMLName xml.Name `xml:"testsuite"`
Tests int `xml:"tests,attr"`
Failures int `xml:"failures,attr"`
Time string `xml:"time,attr"`
Name string `xml:"name,attr"`
Properties []JUnitProperty `xml:"properties>property,omitempty"`
TestCases []JUnitTestCase `xml:"testcase"`
}
// JUnitTestCase is a single test case with its result.
type JUnitTestCase struct {
XMLName xml.Name `xml:"testcase"`
Classname string `xml:"classname,attr"`
Name string `xml:"name,attr"`
Time string `xml:"time,attr"`
SkipMessage *JUnitSkipMessage `xml:"skipped,omitempty"`
Failure *JUnitFailure `xml:"failure,omitempty"`
}
// JUnitSkipMessage contains the reason why a testcase was skipped.
type JUnitSkipMessage struct {
Message string `xml:"message,attr"`
}
// JUnitProperty represents a key/value pair used to define properties.
type JUnitProperty struct {
Name string `xml:"name,attr"`
Value string `xml:"value,attr"`
}
// JUnitFailure contains data related to a failed test.
type JUnitFailure struct {
Message string `xml:"message,attr"`
Type string `xml:"type,attr"`
Contents string `xml:",chardata"`
}
type jUnitReportXML struct{}
// NewJUnitReportXML Constructor
func NewJUnitReportXML() Formatter {
return &jUnitReportXML{}
}
// JUnitReportXML writes a JUnit xml representation of the given report to w
// in the format described at http://windyroad.org/dl/Open%20Source/JUnit.xsd
func (j *jUnitReportXML) WriteTestOutput(testSuiteResults []*TestSuiteResult, noXMLHeader bool, w io.Writer) error {
suites := JUnitTestSuites{}
// convert TestSuiteResults to JUnit test suites
for _, testSuiteResult := range testSuiteResults {
ts := j.createJUnitTestSuite(testSuiteResult)
// properties
ts.Properties = append(ts.Properties, JUnitProperty{"helm-unittest.version", "1.6"})
// individual test cases
for _, test := range testSuiteResult.TestsResult {
testCase := j.createJUnitTestCase(determineClassnameFromDisplayName(testSuiteResult.DisplayName), test)
// Write when a test is failed
if !test.Passed {
ts.Failures++
testCase.Failure = j.createJUnitFailure("Failed", "", test.stringify())
}
ts.TestCases = append(ts.TestCases, testCase)
}
suites.Suites = append(suites.Suites, ts)
}
// to xml
if err := writeContentToFile(noXMLHeader, suites, w); err != nil {
return err
}
return nil
}
func (j *jUnitReportXML) createJUnitTestSuite(testSuiteResult *TestSuiteResult) JUnitTestSuite {
return JUnitTestSuite{
Tests: len(testSuiteResult.TestsResult),
Failures: 0,
Time: formatDuration(testSuiteResult.calculateTestSuiteDuration()),
Name: testSuiteResult.DisplayName,
Properties: []JUnitProperty{},
TestCases: []JUnitTestCase{},
}
}
func (j *jUnitReportXML) createJUnitTestCase(className string, testJobResult *TestJobResult) JUnitTestCase {
return JUnitTestCase{
Classname: className,
Name: testJobResult.DisplayName,
Time: formatDuration(testJobResult.Duration),
Failure: nil,
}
}
func (j *jUnitReportXML) createJUnitFailure(message, failureType, content string) *JUnitFailure {
return &JUnitFailure{
Message: message,
Type: failureType,
Contents: content,
}
}