diff --git a/go-junit-report.go b/go-junit-report.go index c44e4a3..d001ddf 100644 --- a/go-junit-report.go +++ b/go-junit-report.go @@ -6,11 +6,13 @@ import ( "os" ) -var noXmlHeader bool -var packageName string +var ( + noXMLHeader bool + packageName string +) func init() { - flag.BoolVar(&noXmlHeader, "no-xml-header", false, "do not print xml header") + flag.BoolVar(&noXMLHeader, "no-xml-header", false, "do not print xml header") flag.StringVar(&packageName, "package-name", "", "specify a package name (compiled test have no package name in output)") } @@ -25,7 +27,7 @@ func main() { } // Write xml - err = JUnitReportXML(report, noXmlHeader, os.Stdout) + err = JUnitReportXML(report, noXMLHeader, os.Stdout) if err != nil { fmt.Printf("Error writing XML: %s\n", err) os.Exit(1) diff --git a/go-junit-report_test.go b/go-junit-report_test.go index a657663..441f8af 100644 --- a/go-junit-report_test.go +++ b/go-junit-report_test.go @@ -14,11 +14,11 @@ type TestCase struct { name string reportName string report *Report - noXmlHeader bool + noXMLHeader bool packageName string } -var testCases []TestCase = []TestCase{ +var testCases = []TestCase{ { name: "01-pass.txt", reportName: "01-report.xml", @@ -155,7 +155,7 @@ var testCases []TestCase = []TestCase{ }, }, }, - noXmlHeader: true, + noXMLHeader: true, }, { name: "06-mixed.txt", @@ -205,7 +205,7 @@ var testCases []TestCase = []TestCase{ }, }, }, - noXmlHeader: true, + noXMLHeader: true, }, { name: "07-compiled_test.txt", @@ -308,7 +308,7 @@ func TestJUnitFormatter(t *testing.T) { var junitReport bytes.Buffer - if err = JUnitReportXML(testCase.report, testCase.noXmlHeader, &junitReport); err != nil { + if err = JUnitReportXML(testCase.report, testCase.noXMLHeader, &junitReport); err != nil { t.Fatal(err) } diff --git a/junit-formatter.go b/junit-formatter.go index 03cff30..e247612 100644 --- a/junit-formatter.go +++ b/junit-formatter.go @@ -9,11 +9,14 @@ import ( "strings" ) +// JUnitTestSuites is a collection of JUnit test suites. type JUnitTestSuites struct { XMLName xml.Name `xml:"testsuites"` Suites []JUnitTestSuite } +// 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"` @@ -24,6 +27,7 @@ type JUnitTestSuite struct { TestCases []JUnitTestCase } +// JUnitTestCase is a single test case with its result. type JUnitTestCase struct { XMLName xml.Name `xml:"testcase"` Classname string `xml:"classname,attr"` @@ -33,31 +37,27 @@ type JUnitTestCase struct { 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"` } -func NewJUnitProperty(name, value string) JUnitProperty { - return JUnitProperty{ - Name: name, - Value: value, - } -} - -// JUnitReportXML writes a junit xml representation of the given report to w +// 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 JUnitReportXML(report *Report, noXmlHeader bool, w io.Writer) error { +func JUnitReportXML(report *Report, noXMLHeader bool, w io.Writer) error { suites := JUnitTestSuites{} // convert Report to JUnit test suites @@ -77,7 +77,7 @@ func JUnitReportXML(report *Report, noXmlHeader bool, w io.Writer) error { } // properties - ts.Properties = append(ts.Properties, NewJUnitProperty("go.version", runtime.Version())) + ts.Properties = append(ts.Properties, JUnitProperty{"go.version", runtime.Version()}) // individual test cases for _, test := range pkg.Tests { @@ -89,8 +89,7 @@ func JUnitReportXML(report *Report, noXmlHeader bool, w io.Writer) error { } if test.Result == FAIL { - ts.Failures += 1 - + ts.Failures++ testCase.Failure = &JUnitFailure{ Message: "Failed", Type: "", @@ -116,7 +115,7 @@ func JUnitReportXML(report *Report, noXmlHeader bool, w io.Writer) error { writer := bufio.NewWriter(w) - if !noXmlHeader { + if !noXMLHeader { writer.WriteString(xml.Header) } @@ -130,7 +129,7 @@ func JUnitReportXML(report *Report, noXmlHeader bool, w io.Writer) error { func countFailures(tests []Test) (result int) { for _, test := range tests { if test.Result == FAIL { - result += 1 + result++ } } return diff --git a/parser.go b/parser.go index 87ef254..d414897 100644 --- a/parser.go +++ b/parser.go @@ -8,24 +8,29 @@ import ( "strings" ) +// Result represents a test result. type Result int +// Test result constants const ( PASS Result = iota FAIL SKIP ) +// Report is a collection of package tests. type Report struct { Packages []Package } +// Package contains the test results of a single package. type Package struct { Name string Time int Tests []Test } +// Test contains the results of a single test. type Test struct { Name string Time int @@ -38,13 +43,16 @@ var ( regexResult = regexp.MustCompile(`^(ok|FAIL)\s+(.+)\s(\d+\.\d+)s$`) ) -func Parse(r io.Reader, specifiedPackageName string) (*Report, error) { +// Parse parses go test output from reader r and returns a report with the +// results. An optional pkgName can be given, which is used in case a package +// result line is missing. +func Parse(r io.Reader, pkgName string) (*Report, error) { reader := bufio.NewReader(r) report := &Report{make([]Package, 0)} // keep track of tests we find - tests := make([]Test, 0) + var tests []Test // sum of tests' time, use this if current test has no result line (when it is compiled test) testsTime := 0 @@ -115,9 +123,9 @@ func Parse(r io.Reader, specifiedPackageName string) (*Report, error) { tests = append(tests, *test) } - if len(tests) > 0 { //no result line found + if len(tests) > 0 { // no result line found report.Packages = append(report.Packages, Package{ - Name: specifiedPackageName, + Name: pkgName, Time: testsTime, Tests: tests, })