allow randomizing scenario order

Этот коммит содержится в:
Matthew Rothenberg 2017-04-24 21:10:55 -04:00
родитель 834d5841c7
коммит 4a754b26a5
3 изменённых файлов: 35 добавлений и 1 удалений

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

@ -13,6 +13,13 @@ type Options struct {
// Print step definitions found and exit
ShowStepDefinitions bool
// Run scenarios in random order.
//
// This is especially helpful for detecting situations
// where you have state leaking between scenarios, which
// can cause flickering or fragile tests.
RandomOrder bool
// Stops on the first failure
StopOnFailure bool

12
run.go
Просмотреть файл

@ -3,7 +3,9 @@ package godog
import (
"fmt"
"io"
"math/rand"
"os"
"time"
"github.com/DATA-DOG/godog/colors"
)
@ -11,6 +13,7 @@ import (
type initializer func(*Suite)
type runner struct {
randomOrder bool
stopOnFailure bool
features []*feature
fmt Formatter
@ -30,6 +33,7 @@ func (r *runner) concurrent(rate int) (failed bool) {
}
suite := &Suite{
fmt: r.fmt,
randomOrder: r.randomOrder,
stopOnFailure: r.stopOnFailure,
features: []*feature{feat},
}
@ -54,6 +58,7 @@ func (r *runner) concurrent(rate int) (failed bool) {
func (r *runner) run() (failed bool) {
suite := &Suite{
fmt: r.fmt,
randomOrder: r.randomOrder,
stopOnFailure: r.stopOnFailure,
features: r.features,
}
@ -110,9 +115,16 @@ func RunWithOptions(suite string, contextInitializer func(suite *Suite), opt Opt
fmt: formatter(suite, output),
initializer: contextInitializer,
features: features,
randomOrder: opt.RandomOrder,
stopOnFailure: opt.StopOnFailure,
}
if opt.RandomOrder {
// TODO(mroth): allow for seed to be specified in options,
// and print it at the end of a run for replication purposes
rand.Seed(time.Now().UTC().UnixNano())
}
var failed bool
if opt.Concurrency > 1 {
failed = r.concurrent(opt.Concurrency)

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

@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"io"
"math/rand"
"os"
"path/filepath"
"reflect"
@ -49,6 +50,7 @@ type Suite struct {
fmt Formatter
failed bool
randomOrder bool
stopOnFailure bool
// suite event handlers
@ -330,7 +332,20 @@ func (s *Suite) runOutline(outline *gherkin.ScenarioOutline, b *gherkin.Backgrou
func (s *Suite) runFeature(f *feature) {
s.fmt.Feature(f.Feature, f.Path, f.Content)
for _, scenario := range f.ScenarioDefinitions {
// make a local copy of the feature scenario defenitions,
// then shuffle it if we are randomizing scenarios
scenarios := make([]interface{}, len(f.ScenarioDefinitions))
if s.randomOrder {
perm := rand.Perm(len(f.ScenarioDefinitions))
for i, v := range perm {
scenarios[v] = f.ScenarioDefinitions[i]
}
} else {
copy(scenarios, f.ScenarioDefinitions)
}
for _, scenario := range scenarios {
var err error
if f.Background != nil {
s.fmt.Node(f.Background)