exit status on failure, test godog with godog on travis

Этот коммит содержится в:
gedi 2015-06-17 17:58:22 +03:00
родитель a3ef3361f8
коммит 743083181e
5 изменённых файлов: 88 добавлений и 17 удалений

Просмотреть файл

@ -6,7 +6,12 @@ go:
- tip - tip
script: script:
# pull all dependencies
- go get -t ./... - go get -t ./...
# run standard go tests
- go test -v ./... - go test -v ./...
- go test -race ./... - go test -race ./...
# test me with myself
- go run cmd/godog/main.go

Просмотреть файл

@ -16,19 +16,21 @@ func main() {
stdout := ansicolor.NewAnsiColorWriter(os.Stdout) stdout := ansicolor.NewAnsiColorWriter(os.Stdout)
builtFile := fmt.Sprintf("%s/%dgodog.go", os.TempDir(), time.Now().UnixNano()) builtFile := fmt.Sprintf("%s/%dgodog.go", os.TempDir(), time.Now().UnixNano())
defer os.Remove(builtFile) // comment out for debug
buf, err := godog.Build() buf, err := godog.Build()
if err != nil { if err != nil {
os.Remove(builtFile)
panic(err) panic(err)
} }
w, err := os.Create(builtFile) w, err := os.Create(builtFile)
if err != nil { if err != nil {
os.Remove(builtFile)
panic(err) panic(err)
} }
_, err = w.Write(buf) _, err = w.Write(buf)
if err != nil { if err != nil {
os.Remove(builtFile)
panic(err) panic(err)
} }
w.Close() w.Close()
@ -43,8 +45,10 @@ func main() {
err = cmd.Run() err = cmd.Run()
switch err.(type) { switch err.(type) {
case *exec.ExitError: case *exec.ExitError:
os.Remove(builtFile)
os.Exit(1) os.Exit(1)
case *exec.Error: case *exec.Error:
os.Remove(builtFile)
panic(err) panic(err)
} }
} }

Просмотреть файл

@ -3,6 +3,7 @@ package godog
import ( import (
"flag" "flag"
"fmt" "fmt"
"os"
"reflect" "reflect"
"regexp" "regexp"
"runtime" "runtime"
@ -10,6 +11,14 @@ import (
"github.com/DATA-DOG/godog/gherkin" "github.com/DATA-DOG/godog/gherkin"
) )
type stepsStatus int
const (
stepsStatusPassed stepsStatus = iota
stepsStatusFailed
stepsStatusUndefined
)
type BeforeScenarioHandler interface { type BeforeScenarioHandler interface {
BeforeScenario(scenario *gherkin.Scenario) BeforeScenario(scenario *gherkin.Scenario)
} }
@ -66,7 +75,7 @@ type suite struct {
features []*gherkin.Feature features []*gherkin.Feature
fmt Formatter fmt Formatter
stop bool failed bool
} }
// New initializes a suite which supports the Suite // New initializes a suite which supports the Suite
@ -122,12 +131,15 @@ func (s *suite) Run() {
for _, f := range s.features { for _, f := range s.features {
s.runFeature(f) s.runFeature(f)
if s.stop { if s.failed && cfg.stopOnFailure {
// stop on first failure // stop on first failure
break break
} }
} }
s.fmt.Summary() s.fmt.Summary()
if s.failed {
os.Exit(1)
}
} }
func (s *suite) runStep(step *gherkin.Step) (err error) { func (s *suite) runStep(step *gherkin.Step) (err error) {
@ -168,18 +180,21 @@ func (s *suite) runStep(step *gherkin.Step) (err error) {
return return
} }
func (s *suite) runSteps(steps []*gherkin.Step) bool { func (s *suite) runSteps(steps []*gherkin.Step) (st stepsStatus) {
var failed bool
for _, step := range steps { for _, step := range steps {
if failed { if st != stepsStatusPassed {
s.fmt.Skipped(step) s.fmt.Skipped(step)
continue continue
} }
if err := s.runStep(step); err != nil { err := s.runStep(step)
failed = true switch {
case err == errPending:
st = stepsStatusUndefined
case err != nil:
st = stepsStatusFailed
} }
} }
return failed return
} }
func (s *suite) skipSteps(steps []*gherkin.Step) { func (s *suite) skipSteps(steps []*gherkin.Step) {
@ -191,7 +206,7 @@ func (s *suite) skipSteps(steps []*gherkin.Step) {
func (s *suite) runFeature(f *gherkin.Feature) { func (s *suite) runFeature(f *gherkin.Feature) {
s.fmt.Node(f) s.fmt.Node(f)
for _, scenario := range f.Scenarios { for _, scenario := range f.Scenarios {
var failed bool var status stepsStatus
// run before scenario handlers // run before scenario handlers
for _, h := range s.beforeScenarioHandlers { for _, h := range s.beforeScenarioHandlers {
@ -201,23 +216,28 @@ func (s *suite) runFeature(f *gherkin.Feature) {
// background // background
if f.Background != nil { if f.Background != nil {
s.fmt.Node(f.Background) s.fmt.Node(f.Background)
failed = s.runSteps(f.Background.Steps) status = s.runSteps(f.Background.Steps)
} }
// scenario // scenario
s.fmt.Node(scenario) s.fmt.Node(scenario)
if failed { switch {
case status == stepsStatusFailed:
s.skipSteps(scenario.Steps) s.skipSteps(scenario.Steps)
} else { case status == stepsStatusUndefined:
failed = s.runSteps(scenario.Steps) s.skipSteps(scenario.Steps)
default:
status = s.runSteps(scenario.Steps)
} }
if failed && cfg.stopOnFailure { if status == stepsStatusFailed {
s.stop = true s.failed = true
if cfg.stopOnFailure {
return return
} }
} }
} }
}
func (st *suite) printStepDefinitions() { func (st *suite) printStepDefinitions() {
var longest int var longest int

Просмотреть файл

@ -18,6 +18,8 @@ func (s *suiteFeature) BeforeScenario(scenario *gherkin.Scenario) {
cfg.paths = []string{} cfg.paths = []string{}
// reset hook test references // reset hook test references
s.befScenarioHook = nil s.befScenarioHook = nil
// reset formatter, which collects all details
s.fmt = &testFormatter{}
} }
func (s *suiteFeature) iHaveBeforeScenarioHook(args ...*Arg) error { func (s *suiteFeature) iHaveBeforeScenarioHook(args ...*Arg) error {

40
utils_test.go Обычный файл
Просмотреть файл

@ -0,0 +1,40 @@
package godog
import "github.com/DATA-DOG/godog/gherkin"
type testFormatter struct {
features []*gherkin.Feature
scenarios []*gherkin.Scenario
failed []*failed
passed []*passed
skipped []*skipped
undefined []*undefined
}
func (f *testFormatter) Node(node interface{}) {
switch t := node.(type) {
case *gherkin.Feature:
f.features = append(f.features, t)
case *gherkin.Scenario:
f.scenarios = append(f.scenarios, t)
}
}
func (f *testFormatter) Summary() {}
func (f *testFormatter) Passed(step *gherkin.Step, match *stepMatchHandler) {
f.passed = append(f.passed, &passed{step})
}
func (f *testFormatter) Skipped(step *gherkin.Step) {
f.skipped = append(f.skipped, &skipped{step})
}
func (f *testFormatter) Undefined(step *gherkin.Step) {
f.undefined = append(f.undefined, &undefined{step})
}
func (f *testFormatter) Failed(step *gherkin.Step, match *stepMatchHandler, err error) {
f.failed = append(f.failed, &failed{step, err})
}