tests junit formatter
Этот коммит содержится в:
		
							родитель
							
								
									ef794d57ca
								
							
						
					
					
						коммит
						df5310a062
					
				
					 5 изменённых файлов: 202 добавлений и 18 удалений
				
			
		| 
						 | 
					@ -261,7 +261,7 @@ Feature: cucumber json formatter
 | 
				
			||||||
                  },
 | 
					                  },
 | 
				
			||||||
                  "result": {
 | 
					                  "result": {
 | 
				
			||||||
                    "status": "passed",
 | 
					                    "status": "passed",
 | 
				
			||||||
                    "duration": -1
 | 
					                    "duration": 0
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
| 
						 | 
					@ -274,7 +274,7 @@ Feature: cucumber json formatter
 | 
				
			||||||
                  "result": {
 | 
					                  "result": {
 | 
				
			||||||
                    "status": "failed",
 | 
					                    "status": "failed",
 | 
				
			||||||
                    "error_message": "intentional failure",
 | 
					                    "error_message": "intentional failure",
 | 
				
			||||||
                    "duration": -1
 | 
					                    "duration": 0
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              ]
 | 
					              ]
 | 
				
			||||||
| 
						 | 
					@ -329,7 +329,7 @@ Feature: cucumber json formatter
 | 
				
			||||||
                  },
 | 
					                  },
 | 
				
			||||||
                  "result": {
 | 
					                  "result": {
 | 
				
			||||||
                    "status": "passed",
 | 
					                    "status": "passed",
 | 
				
			||||||
                    "duration": -1
 | 
					                    "duration": 0
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              ]
 | 
					              ]
 | 
				
			||||||
| 
						 | 
					@ -352,7 +352,7 @@ Feature: cucumber json formatter
 | 
				
			||||||
                  "result": {
 | 
					                  "result": {
 | 
				
			||||||
                    "status": "failed",
 | 
					                    "status": "failed",
 | 
				
			||||||
                    "error_message": "intentional failure",
 | 
					                    "error_message": "intentional failure",
 | 
				
			||||||
                    "duration": -1
 | 
					                    "duration": 0
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              ]
 | 
					              ]
 | 
				
			||||||
| 
						 | 
					@ -452,7 +452,7 @@ Feature: cucumber json formatter
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "result": {
 | 
					                "result": {
 | 
				
			||||||
                  "status": "passed",
 | 
					                  "status": "passed",
 | 
				
			||||||
                  "duration": -1
 | 
					                  "duration": 0
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
| 
						 | 
					@ -505,7 +505,7 @@ Feature: cucumber json formatter
 | 
				
			||||||
                  },
 | 
					                  },
 | 
				
			||||||
                  "result": {
 | 
					                  "result": {
 | 
				
			||||||
                    "status": "passed",
 | 
					                    "status": "passed",
 | 
				
			||||||
                    "duration": -1
 | 
					                    "duration": 0
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										27
									
								
								fmt_junit.go
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								fmt_junit.go
									
										
									
									
									
								
							| 
						 | 
					@ -62,14 +62,12 @@ func (j *junitFormatter) Node(node interface{}) {
 | 
				
			||||||
	switch t := node.(type) {
 | 
						switch t := node.(type) {
 | 
				
			||||||
	case *gherkin.ScenarioOutline:
 | 
						case *gherkin.ScenarioOutline:
 | 
				
			||||||
		j.outline = t
 | 
							j.outline = t
 | 
				
			||||||
 | 
							j.outlineExample = 0
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	case *gherkin.Scenario:
 | 
						case *gherkin.Scenario:
 | 
				
			||||||
		tcase.Name = t.Name
 | 
							tcase.Name = t.Name
 | 
				
			||||||
		suite.Tests++
 | 
							suite.Tests++
 | 
				
			||||||
		j.suite.Tests++
 | 
							j.suite.Tests++
 | 
				
			||||||
	case *gherkin.Examples:
 | 
					 | 
				
			||||||
		j.outlineExample = 0
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	case *gherkin.TableRow:
 | 
						case *gherkin.TableRow:
 | 
				
			||||||
		j.outlineExample++
 | 
							j.outlineExample++
 | 
				
			||||||
		tcase.Name = fmt.Sprintf("%s #%d", j.outline.Name, j.outlineExample)
 | 
							tcase.Name = fmt.Sprintf("%s #%d", j.outline.Name, j.outlineExample)
 | 
				
			||||||
| 
						 | 
					@ -78,9 +76,6 @@ func (j *junitFormatter) Node(node interface{}) {
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(suite.TestCases) > 0 {
 | 
					 | 
				
			||||||
		suite.current().Time = timeNowFunc().Sub(j.caseStarted).String()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	j.caseStarted = timeNowFunc()
 | 
						j.caseStarted = timeNowFunc()
 | 
				
			||||||
	suite.TestCases = append(suite.TestCases, tcase)
 | 
						suite.TestCases = append(suite.TestCases, tcase)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -91,6 +86,7 @@ func (j *junitFormatter) Failed(step *gherkin.Step, match *StepDef, err error) {
 | 
				
			||||||
	j.suite.Failures++
 | 
						j.suite.Failures++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tcase := suite.current()
 | 
						tcase := suite.current()
 | 
				
			||||||
 | 
						tcase.Time = timeNowFunc().Sub(j.caseStarted).String()
 | 
				
			||||||
	tcase.Status = "failed"
 | 
						tcase.Status = "failed"
 | 
				
			||||||
	tcase.Failure = &junitFailure{
 | 
						tcase.Failure = &junitFailure{
 | 
				
			||||||
		Message: fmt.Sprintf("%s %s: %s", step.Type, step.Text, err.Error()),
 | 
							Message: fmt.Sprintf("%s %s: %s", step.Type, step.Text, err.Error()),
 | 
				
			||||||
| 
						 | 
					@ -101,18 +97,31 @@ func (j *junitFormatter) Passed(step *gherkin.Step, match *StepDef) {
 | 
				
			||||||
	suite := j.current()
 | 
						suite := j.current()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tcase := suite.current()
 | 
						tcase := suite.current()
 | 
				
			||||||
 | 
						tcase.Time = timeNowFunc().Sub(j.caseStarted).String()
 | 
				
			||||||
	tcase.Status = "passed"
 | 
						tcase.Status = "passed"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (j *junitFormatter) Skipped(step *gherkin.Step) {
 | 
					func (j *junitFormatter) Skipped(step *gherkin.Step) {
 | 
				
			||||||
 | 
						suite := j.current()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tcase := suite.current()
 | 
				
			||||||
 | 
						tcase.Time = timeNowFunc().Sub(j.caseStarted).String()
 | 
				
			||||||
 | 
						tcase.Error = append(tcase.Error, &junitError{
 | 
				
			||||||
 | 
							Type:    "skipped",
 | 
				
			||||||
 | 
							Message: fmt.Sprintf("%s %s", step.Type, step.Text),
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (j *junitFormatter) Undefined(step *gherkin.Step) {
 | 
					func (j *junitFormatter) Undefined(step *gherkin.Step) {
 | 
				
			||||||
	suite := j.current()
 | 
						suite := j.current()
 | 
				
			||||||
 | 
						tcase := suite.current()
 | 
				
			||||||
 | 
						if tcase.Status != "undefined" {
 | 
				
			||||||
 | 
							// do not count two undefined steps as another error
 | 
				
			||||||
		suite.Errors++
 | 
							suite.Errors++
 | 
				
			||||||
		j.suite.Errors++
 | 
							j.suite.Errors++
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tcase := suite.current()
 | 
						tcase.Time = timeNowFunc().Sub(j.caseStarted).String()
 | 
				
			||||||
	tcase.Status = "undefined"
 | 
						tcase.Status = "undefined"
 | 
				
			||||||
	tcase.Error = append(tcase.Error, &junitError{
 | 
						tcase.Error = append(tcase.Error, &junitError{
 | 
				
			||||||
		Type:    "undefined",
 | 
							Type:    "undefined",
 | 
				
			||||||
| 
						 | 
					@ -126,6 +135,7 @@ func (j *junitFormatter) Pending(step *gherkin.Step, match *StepDef) {
 | 
				
			||||||
	j.suite.Errors++
 | 
						j.suite.Errors++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tcase := suite.current()
 | 
						tcase := suite.current()
 | 
				
			||||||
 | 
						tcase.Time = timeNowFunc().Sub(j.caseStarted).String()
 | 
				
			||||||
	tcase.Status = "pending"
 | 
						tcase.Status = "pending"
 | 
				
			||||||
	tcase.Error = append(tcase.Error, &junitError{
 | 
						tcase.Error = append(tcase.Error, &junitError{
 | 
				
			||||||
		Type:    "pending",
 | 
							Type:    "pending",
 | 
				
			||||||
| 
						 | 
					@ -134,6 +144,9 @@ func (j *junitFormatter) Pending(step *gherkin.Step, match *StepDef) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (j *junitFormatter) Summary() {
 | 
					func (j *junitFormatter) Summary() {
 | 
				
			||||||
 | 
						if j.current() != nil {
 | 
				
			||||||
 | 
							j.current().Time = timeNowFunc().Sub(j.featStarted).String()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	j.suite.Time = timeNowFunc().Sub(j.started).String()
 | 
						j.suite.Time = timeNowFunc().Sub(j.started).String()
 | 
				
			||||||
	io.WriteString(j.out, xml.Header)
 | 
						io.WriteString(j.out, xml.Header)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										169
									
								
								fmt_junit_test.go
									
										
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										169
									
								
								fmt_junit_test.go
									
										
									
									
									
										Обычный файл
									
								
							| 
						 | 
					@ -0,0 +1,169 @@
 | 
				
			||||||
 | 
					package godog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"encoding/xml"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/DATA-DOG/godog/colors"
 | 
				
			||||||
 | 
						"github.com/DATA-DOG/godog/gherkin"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var sampleGherkinFeature = `
 | 
				
			||||||
 | 
					Feature: junit formatter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Background:
 | 
				
			||||||
 | 
					    Given passing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: passing scenario
 | 
				
			||||||
 | 
					    Then passing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: failing scenario
 | 
				
			||||||
 | 
					    When failing
 | 
				
			||||||
 | 
					    Then passing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: pending scenario
 | 
				
			||||||
 | 
					    When pending
 | 
				
			||||||
 | 
					    Then passing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: undefined scenario
 | 
				
			||||||
 | 
					    When undefined
 | 
				
			||||||
 | 
					    Then next undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario Outline: outline
 | 
				
			||||||
 | 
					    Given <one>
 | 
				
			||||||
 | 
					    When <two>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Examples:
 | 
				
			||||||
 | 
					      | one     | two     |
 | 
				
			||||||
 | 
					      | passing | passing |
 | 
				
			||||||
 | 
					      | passing | failing |
 | 
				
			||||||
 | 
					      | passing | pending |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Examples:
 | 
				
			||||||
 | 
					      | one     | two       |
 | 
				
			||||||
 | 
					      | passing | undefined |
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestJUnitSimpleFeature(t *testing.T) {
 | 
				
			||||||
 | 
						feat, err := gherkin.ParseFeature(strings.NewReader(sampleGherkinFeature))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var buf bytes.Buffer
 | 
				
			||||||
 | 
						w := colors.Uncolored(&buf)
 | 
				
			||||||
 | 
						s := &Suite{
 | 
				
			||||||
 | 
							fmt: junitFunc("junit", w),
 | 
				
			||||||
 | 
							features: []*feature{&feature{
 | 
				
			||||||
 | 
								Path:    "any.feature",
 | 
				
			||||||
 | 
								Feature: feat,
 | 
				
			||||||
 | 
								Content: []byte(sampleGherkinFeature),
 | 
				
			||||||
 | 
							}},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s.Step(`^passing$`, func() error { return nil })
 | 
				
			||||||
 | 
						s.Step(`^failing$`, func() error { return fmt.Errorf("errored") })
 | 
				
			||||||
 | 
						s.Step(`^pending$`, func() error { return ErrPending })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expected := junitPackageSuite{
 | 
				
			||||||
 | 
							Name:     "junit",
 | 
				
			||||||
 | 
							Tests:    8,
 | 
				
			||||||
 | 
							Skipped:  0,
 | 
				
			||||||
 | 
							Failures: 2,
 | 
				
			||||||
 | 
							Errors:   4,
 | 
				
			||||||
 | 
							Time:     "0s",
 | 
				
			||||||
 | 
							TestSuites: []*junitTestSuite{{
 | 
				
			||||||
 | 
								Name:     "junit formatter",
 | 
				
			||||||
 | 
								Tests:    8,
 | 
				
			||||||
 | 
								Skipped:  0,
 | 
				
			||||||
 | 
								Failures: 2,
 | 
				
			||||||
 | 
								Errors:   4,
 | 
				
			||||||
 | 
								Time:     "0s",
 | 
				
			||||||
 | 
								TestCases: []*junitTestCase{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:   "passing scenario",
 | 
				
			||||||
 | 
										Status: "passed",
 | 
				
			||||||
 | 
										Time:   "0s",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:   "failing scenario",
 | 
				
			||||||
 | 
										Status: "failed",
 | 
				
			||||||
 | 
										Time:   "0s",
 | 
				
			||||||
 | 
										Failure: &junitFailure{
 | 
				
			||||||
 | 
											Message: "Step failing: errored",
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										Error: []*junitError{
 | 
				
			||||||
 | 
											{Message: "Step passing", Type: "skipped"},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:   "pending scenario",
 | 
				
			||||||
 | 
										Status: "pending",
 | 
				
			||||||
 | 
										Time:   "0s",
 | 
				
			||||||
 | 
										Error: []*junitError{
 | 
				
			||||||
 | 
											{Message: "Step pending: TODO: write pending definition", Type: "pending"},
 | 
				
			||||||
 | 
											{Message: "Step passing", Type: "skipped"},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:   "undefined scenario",
 | 
				
			||||||
 | 
										Status: "undefined",
 | 
				
			||||||
 | 
										Time:   "0s",
 | 
				
			||||||
 | 
										Error: []*junitError{
 | 
				
			||||||
 | 
											{Message: "Step undefined", Type: "undefined"},
 | 
				
			||||||
 | 
											{Message: "Step next undefined", Type: "undefined"},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:   "outline #1",
 | 
				
			||||||
 | 
										Status: "passed",
 | 
				
			||||||
 | 
										Time:   "0s",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:   "outline #2",
 | 
				
			||||||
 | 
										Status: "failed",
 | 
				
			||||||
 | 
										Time:   "0s",
 | 
				
			||||||
 | 
										Failure: &junitFailure{
 | 
				
			||||||
 | 
											Message: "Step failing: errored",
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:   "outline #3",
 | 
				
			||||||
 | 
										Status: "pending",
 | 
				
			||||||
 | 
										Time:   "0s",
 | 
				
			||||||
 | 
										Error: []*junitError{
 | 
				
			||||||
 | 
											{Message: "Step pending: TODO: write pending definition", Type: "pending"},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:   "outline #4",
 | 
				
			||||||
 | 
										Status: "undefined",
 | 
				
			||||||
 | 
										Time:   "0s",
 | 
				
			||||||
 | 
										Error: []*junitError{
 | 
				
			||||||
 | 
											{Message: "Step undefined", Type: "undefined"},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							}},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s.run()
 | 
				
			||||||
 | 
						s.fmt.Summary()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var exp bytes.Buffer
 | 
				
			||||||
 | 
						io.WriteString(&exp, xml.Header)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enc := xml.NewEncoder(&exp)
 | 
				
			||||||
 | 
						enc.Indent("", "  ")
 | 
				
			||||||
 | 
						if err := enc.Encode(expected); err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if buf.String() != exp.String() {
 | 
				
			||||||
 | 
							t.Fatalf("expected output does not match: %s", buf.String())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -415,9 +415,8 @@ func (s *suiteContext) theRenderJSONWillBe(docstring *gherkin.DocString) error {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var actual []cukeFeatureJSON
 | 
						var actual []cukeFeatureJSON
 | 
				
			||||||
	re := regexp.MustCompile(`"duration":\s*\d+`)
 | 
						replaced := loc.ReplaceAllString(s.out.String(), `"suite_test.go:0"`)
 | 
				
			||||||
	replaced := re.ReplaceAllString(s.out.String(), `"duration": -1`)
 | 
						if err := json.Unmarshal([]byte(replaced), &actual); err != nil {
 | 
				
			||||||
	if err := json.Unmarshal([]byte(loc.ReplaceAllString(replaced, `"suite_test.go:0"`)), &actual); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,9 @@ import (
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// this zeroes the time throughout whole test suite
 | 
				
			||||||
 | 
					// and makes it easier to assert output
 | 
				
			||||||
 | 
					// activated only when godog tests are being run
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	timeNowFunc = func() time.Time {
 | 
						timeNowFunc = func() time.Time {
 | 
				
			||||||
		return time.Time{}
 | 
							return time.Time{}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче