diff --git a/fmt_junit.go b/fmt_junit.go index 624d027..e20b9cd 100644 --- a/fmt_junit.go +++ b/fmt_junit.go @@ -3,38 +3,34 @@ package godog import ( "encoding/xml" "fmt" - "io" "os" "time" - "github.com/adrianduke/godog/junit" - gherkin "github.com/cucumber/gherkin-go" + "gopkg.in/cucumber/gherkin-go.v3" ) -const JUnitResultsEnv = "JUNIT_RESULTS" - func init() { Format("junit", "Prints out in junit compatible xml format", &junitFormatter{ - JUnit: make(junit.JUnit, 0), + suites: make([]*junitTestSuites, 0), }) } type junitFormatter struct { - junit.JUnit + suites []*junitTestSuites } func (j *junitFormatter) Feature(feature *gherkin.Feature, path string) { - testSuites := &junit.TestSuites{ + testSuites := &junitTestSuites{ Name: feature.Name, - TestSuites: make([]*junit.TestSuite, 0), + TestSuites: make([]*junitTestSuite, 0), } - j.JUnit = append(j.JUnit, testSuites) + j.suites = append(j.suites, testSuites) } func (j *junitFormatter) Node(node interface{}) { - testSuite := &junit.TestSuite{ - TestCases: make([]*junit.TestCase, 0), + testSuite := &junitTestSuite{ + TestCases: make([]*TestCase, 0), Timestamp: time.Now(), } @@ -47,93 +43,165 @@ func (j *junitFormatter) Node(node interface{}) { testSuite.Name = "Background" } - currentSuites := j.JUnit.CurrentSuites() + currentSuites := j.currentSuites() currentSuites.TestSuites = append(currentSuites.TestSuites, testSuite) } func (j *junitFormatter) Failed(step *gherkin.Step, match *StepDef, err error) { - testCase := &junit.TestCase{ + testCase := &TestCase{ Name: step.Text, } - testCase.Failure = &junit.Failure{ + testCase.Failure = &junitFailure{ Contents: err.Error(), } - currentSuites := j.JUnit.CurrentSuites() + currentSuites := j.currentSuites() currentSuites.Failures++ - currentSuite := currentSuites.CurrentSuite() + currentSuite := currentSuites.currentSuite() currentSuite.Failures++ currentSuite.TestCases = append(currentSuite.TestCases, testCase) } func (j *junitFormatter) Passed(step *gherkin.Step, match *StepDef) { - testCase := &junit.TestCase{ + testCase := &TestCase{ Name: step.Text, } - currentSuites := j.JUnit.CurrentSuites() + currentSuites := j.currentSuites() currentSuites.Tests++ - currentSuite := currentSuites.CurrentSuite() + currentSuite := currentSuites.currentSuite() currentSuite.Tests++ currentSuite.TestCases = append(currentSuite.TestCases, testCase) } func (j *junitFormatter) Skipped(step *gherkin.Step) { - testCase := &junit.TestCase{ + testCase := &TestCase{ Name: step.Text, } - currentSuites := j.JUnit.CurrentSuites() - currentSuite := currentSuites.CurrentSuite() + currentSuites := j.currentSuites() + currentSuite := currentSuites.currentSuite() currentSuite.Skipped++ currentSuite.TestCases = append(currentSuite.TestCases, testCase) } func (j *junitFormatter) Undefined(step *gherkin.Step) { - testCase := &junit.TestCase{ + testCase := &TestCase{ Name: step.Text, } - currentSuites := j.JUnit.CurrentSuites() + currentSuites := j.currentSuites() currentSuites.Disabled++ - currentSuite := currentSuites.CurrentSuite() + currentSuite := currentSuites.currentSuite() currentSuite.Disabled++ currentSuite.TestCases = append(currentSuite.TestCases, testCase) } func (j *junitFormatter) Pending(step *gherkin.Step, match *StepDef) { - testCase := &junit.TestCase{ + testCase := &TestCase{ Name: step.Text, } - testCase.Skipped = junit.Skipped{ + testCase.Skipped = &junitSkipped{ Contents: step.Text, } - currentSuites := j.JUnit.CurrentSuites() - currentSuite := currentSuites.CurrentSuite() + currentSuites := j.currentSuites() + currentSuite := currentSuites.currentSuite() currentSuite.Skipped++ currentSuite.TestCases = append(currentSuite.TestCases, testCase) } func (j *junitFormatter) Summary() { - var writer io.Writer - if outputFilePath := os.Getenv(JUnitResultsEnv); outputFilePath != "" { - outputFile, err := os.Create(outputFilePath) - if err != nil { - panic(err.Error()) - } - defer outputFile.Close() - - writer = io.Writer(outputFile) - } else { - writer = os.Stdout - } - - enc := xml.NewEncoder(writer) + enc := xml.NewEncoder(os.Stdout) enc.Indent(" ", " ") - if err := enc.Encode(j.JUnit); err != nil { + if err := enc.Encode(j.suites); err != nil { fmt.Printf("error: %v\n", err) } } + +type junitFailure struct { + Message string `xml:"message,attr"` + Type string `xml:"type,attr"` + Contents string `xml:",chardata"` +} + +type junitError struct { + Message string `xml:"message,attr"` + Type string `xml:"type,attr"` + Contents string `xml:",chardata"` +} + +type junitProperty struct { + Name string `xml:"name,attr"` + Value string `xml:"value,attr"` +} + +type junitSkipped struct { + Contents string `xml:",chardata"` +} + +type SystemErr struct { + Contents string `xml:",chardata"` +} + +type SystemOut struct { + Contents string `xml:",chardata"` +} + +type TestCase struct { + XMLName xml.Name `xml:"testcase"` + Name string `xml:"name,attr"` + Classname string `xml:"classname,attr"` + Assertions string `xml:"assertions,attr"` + Status string `xml:"status,attr"` + Time string `xml:"time,attr"` + Skipped *junitSkipped `xml:"skipped,omitempty"` + Failure *junitFailure `xml:"failure,omitempty"` + Error *junitError `xml:"error,omitempty"` + SystemOut *SystemOut `xml:"system-out,omitempty"` + SystemErr *SystemErr `xml:"system-err,omitempty"` +} + +type junitTestSuite 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"` + Disabled int `xml:"disabled,attr"` + Skipped int `xml:"skipped,attr"` + Time string `xml:"time,attr"` + Hostname string `xml:"hostname,attr"` + ID string `xml:"id,attr"` + Package string `xml:"package,attr"` + Timestamp time.Time `xml:"timestamp,attr"` + SystemOut *SystemOut `xml:"system-out,omitempty"` + SystemErr *SystemErr `xml:"system-err,omitempty"` + Properties []*junitProperty `xml:"properties>property,omitempty"` + TestCases []*TestCase +} + +func (ts *junitTestSuite) currentCase() *TestCase { + return ts.TestCases[len(ts.TestCases)-1] +} + +type junitTestSuites struct { + XMLName xml.Name `xml:"testsuites"` + Name string `xml:"name,attr"` + Tests int `xml:"tests,attr"` + Failures int `xml:"failures,attr"` + Errors int `xml:"errors,attr"` + Disabled int `xml:"disabled,attr"` + Time string `xml:"time,attr"` + TestSuites []*junitTestSuite +} + +func (ts *junitTestSuites) currentSuite() *junitTestSuite { + return ts.TestSuites[len(ts.TestSuites)-1] +} + +func (j *junitFormatter) currentSuites() *junitTestSuites { + return j.suites[len(j.suites)-1] +} diff --git a/junit/structs.go b/junit/structs.go index 630efba..770abab 100644 --- a/junit/structs.go +++ b/junit/structs.go @@ -1,93 +1 @@ package junit - -import ( - "encoding/xml" - "time" -) - -type Failure struct { - Message string `xml:"message,attr"` - Type string `xml:"type,attr"` - Contents string `xml:",chardata"` -} - -type Error struct { - Message string `xml:"message,attr"` - Type string `xml:"type,attr"` - Contents string `xml:",chardata"` -} - -type Property struct { - Name string `xml:"name,attr"` - Value string `xml:"value,attr"` -} - -type Skipped struct { - Contents string `xml:",chardata"` -} - -type SystemErr struct { - Contents string `xml:",chardata"` -} - -type SystemOut struct { - Contents string `xml:",chardata"` -} - -type TestCase struct { - XMLName xml.Name `xml:"testcase"` - Name string `xml:"name,attr"` - Classname string `xml:"classname,attr"` - Assertions string `xml:"assertions,attr"` - Status string `xml:"status,attr"` - Time string `xml:"time,attr"` - Skipped *Skipped `xml:"skipped,omitempty"` - Failure *Failure `xml:"failure,omitempty"` - Error *Error `xml:"error,omitempty"` - SystemOut *SystemOut `xml:"system-out,omitempty"` - SystemErr *SystemErr `xml:"system-err,omitempty"` -} - -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"` - Disabled int `xml:"disabled,attr"` - Skipped int `xml:"skipped,attr"` - Time string `xml:"time,attr"` - Hostname string `xml:"hostname,attr"` - ID string `xml:"id,attr"` - Package string `xml:"package,attr"` - Timestamp time.Time `xml:"timestamp,attr"` - SystemOut *SystemOut `xml:"system-out,omitempty"` - SystemErr *SystemErr `xml:"system-err,omitempty"` - Properties []*Property `xml:"properties>property,omitempty"` - TestCases []*TestCase -} - -func (ts *TestSuite) CurrentCase() *TestCase { - return ts.TestCases[len(ts.TestCases)-1] -} - -type TestSuites struct { - XMLName xml.Name `xml:"testsuites"` - Name string `xml:"name,attr"` - Tests int `xml:"tests,attr"` - Failures int `xml:"failures,attr"` - Errors int `xml:"errors,attr"` - Disabled int `xml:"disabled,attr"` - Time string `xml:"time,attr"` - TestSuites []*TestSuite -} - -func (ts *TestSuites) CurrentSuite() *TestSuite { - return ts.TestSuites[len(ts.TestSuites)-1] -} - -type JUnit []*TestSuites - -func (j JUnit) CurrentSuites() *TestSuites { - return j[len(j)-1] -}