arnaucube
arnaucube/mirror-to-giteaPublic Self-hosted repository
mirror-to-gitea/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go
vendor/github.com/onsi/ginkgo/reporters/junit_reporter.goRaw
  1/*
  2
  3JUnit XML Reporter for Ginkgo
  4
  5For usage instructions: http://onsi.github.io/ginkgo/#generating_junit_xml_output
  6
  7*/
  8
  9package reporters
 10
 11import (
 12	"encoding/xml"
 13	"fmt"
 14	"math"
 15	"os"
 16	"path/filepath"
 17	"strings"
 18
 19	"github.com/onsi/ginkgo/config"
 20	"github.com/onsi/ginkgo/types"
 21)
 22
 23type JUnitTestSuite struct {
 24	XMLName   xml.Name        `xml:"testsuite"`
 25	TestCases []JUnitTestCase `xml:"testcase"`
 26	Name      string          `xml:"name,attr"`
 27	Tests     int             `xml:"tests,attr"`
 28	Failures  int             `xml:"failures,attr"`
 29	Errors    int             `xml:"errors,attr"`
 30	Time      float64         `xml:"time,attr"`
 31}
 32
 33type JUnitTestCase struct {
 34	Name           string               `xml:"name,attr"`
 35	ClassName      string               `xml:"classname,attr"`
 36	FailureMessage *JUnitFailureMessage `xml:"failure,omitempty"`
 37	Skipped        *JUnitSkipped        `xml:"skipped,omitempty"`
 38	Time           float64              `xml:"time,attr"`
 39	SystemOut      string               `xml:"system-out,omitempty"`
 40}
 41
 42type JUnitFailureMessage struct {
 43	Type    string `xml:"type,attr"`
 44	Message string `xml:",chardata"`
 45}
 46
 47type JUnitSkipped struct {
 48	Message string `xml:",chardata"`
 49}
 50
 51type JUnitReporter struct {
 52	suite          JUnitTestSuite
 53	filename       string
 54	testSuiteName  string
 55	ReporterConfig config.DefaultReporterConfigType
 56}
 57
 58//NewJUnitReporter creates a new JUnit XML reporter.  The XML will be stored in the passed in filename.
 59func NewJUnitReporter(filename string) *JUnitReporter {
 60	return &JUnitReporter{
 61		filename: filename,
 62	}
 63}
 64
 65func (reporter *JUnitReporter) SpecSuiteWillBegin(ginkgoConfig config.GinkgoConfigType, summary *types.SuiteSummary) {
 66	reporter.suite = JUnitTestSuite{
 67		Name:      summary.SuiteDescription,
 68		TestCases: []JUnitTestCase{},
 69	}
 70	reporter.testSuiteName = summary.SuiteDescription
 71	reporter.ReporterConfig = config.DefaultReporterConfig
 72}
 73
 74func (reporter *JUnitReporter) SpecWillRun(specSummary *types.SpecSummary) {
 75}
 76
 77func (reporter *JUnitReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) {
 78	reporter.handleSetupSummary("BeforeSuite", setupSummary)
 79}
 80
 81func (reporter *JUnitReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {
 82	reporter.handleSetupSummary("AfterSuite", setupSummary)
 83}
 84
 85func failureMessage(failure types.SpecFailure) string {
 86	return fmt.Sprintf("%s\n%s\n%s", failure.ComponentCodeLocation.String(), failure.Message, failure.Location.String())
 87}
 88
 89func (reporter *JUnitReporter) handleSetupSummary(name string, setupSummary *types.SetupSummary) {
 90	if setupSummary.State != types.SpecStatePassed {
 91		testCase := JUnitTestCase{
 92			Name:      name,
 93			ClassName: reporter.testSuiteName,
 94		}
 95
 96		testCase.FailureMessage = &JUnitFailureMessage{
 97			Type:    reporter.failureTypeForState(setupSummary.State),
 98			Message: failureMessage(setupSummary.Failure),
 99		}
100		testCase.SystemOut = setupSummary.CapturedOutput
101		testCase.Time = setupSummary.RunTime.Seconds()
102		reporter.suite.TestCases = append(reporter.suite.TestCases, testCase)
103	}
104}
105
106func (reporter *JUnitReporter) SpecDidComplete(specSummary *types.SpecSummary) {
107	testCase := JUnitTestCase{
108		Name:      strings.Join(specSummary.ComponentTexts[1:], " "),
109		ClassName: reporter.testSuiteName,
110	}
111	if reporter.ReporterConfig.ReportPassed && specSummary.State == types.SpecStatePassed {
112		testCase.SystemOut = specSummary.CapturedOutput
113	}
114	if specSummary.State == types.SpecStateFailed || specSummary.State == types.SpecStateTimedOut || specSummary.State == types.SpecStatePanicked {
115		testCase.FailureMessage = &JUnitFailureMessage{
116			Type:    reporter.failureTypeForState(specSummary.State),
117			Message: failureMessage(specSummary.Failure),
118		}
119		if specSummary.State == types.SpecStatePanicked {
120			testCase.FailureMessage.Message += fmt.Sprintf("\n\nPanic: %s\n\nFull stack:\n%s",
121				specSummary.Failure.ForwardedPanic,
122				specSummary.Failure.Location.FullStackTrace)
123		}
124		testCase.SystemOut = specSummary.CapturedOutput
125	}
126	if specSummary.State == types.SpecStateSkipped || specSummary.State == types.SpecStatePending {
127		testCase.Skipped = &JUnitSkipped{}
128		if specSummary.Failure.Message != "" {
129			testCase.Skipped.Message = failureMessage(specSummary.Failure)
130		}
131	}
132	testCase.Time = specSummary.RunTime.Seconds()
133	reporter.suite.TestCases = append(reporter.suite.TestCases, testCase)
134}
135
136func (reporter *JUnitReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) {
137	reporter.suite.Tests = summary.NumberOfSpecsThatWillBeRun
138	reporter.suite.Time = math.Trunc(summary.RunTime.Seconds()*1000) / 1000
139	reporter.suite.Failures = summary.NumberOfFailedSpecs
140	reporter.suite.Errors = 0
141	if reporter.ReporterConfig.ReportFile != "" {
142		reporter.filename = reporter.ReporterConfig.ReportFile
143		fmt.Printf("\nJUnit path was configured: %s\n", reporter.filename)
144	}
145	filePath, _ := filepath.Abs(reporter.filename)
146	dirPath := filepath.Dir(filePath)
147	err := os.MkdirAll(dirPath, os.ModePerm)
148	if err != nil {
149		fmt.Printf("\nFailed to create JUnit directory: %s\n\t%s", filePath, err.Error())
150	}
151	file, err := os.Create(filePath)
152	if err != nil {
153		fmt.Fprintf(os.Stderr, "Failed to create JUnit report file: %s\n\t%s", filePath, err.Error())
154	}
155	defer file.Close()
156	file.WriteString(xml.Header)
157	encoder := xml.NewEncoder(file)
158	encoder.Indent("  ", "    ")
159	err = encoder.Encode(reporter.suite)
160	if err == nil {
161		fmt.Fprintf(os.Stdout, "\nJUnit report was created: %s\n", filePath)
162	} else {
163		fmt.Fprintf(os.Stderr,"\nFailed to generate JUnit report data:\n\t%s", err.Error())
164	}
165}
166
167func (reporter *JUnitReporter) failureTypeForState(state types.SpecState) string {
168	switch state {
169	case types.SpecStateFailed:
170		return "Failure"
171	case types.SpecStateTimedOut:
172		return "Timeout"
173	case types.SpecStatePanicked:
174		return "Panic"
175	default:
176		return ""
177	}
178}