switch Random opt from bool to int64
This allows for us to propagate the seed value around, and not have to have two different values in Options when we want to allow specification of seed. It does introduce some “magic values”, but the document them in the Options struct docstrings.
Этот коммит содержится в:
родитель
4a754b26a5
коммит
0eed963c63
3 изменённых файлов: 28 добавлений и 17 удалений
15
options.go
15
options.go
|
@ -13,12 +13,17 @@ type Options struct {
|
||||||
// Print step definitions found and exit
|
// Print step definitions found and exit
|
||||||
ShowStepDefinitions bool
|
ShowStepDefinitions bool
|
||||||
|
|
||||||
// Run scenarios in random order.
|
// RandomSeed, if not `0`, will be used to run scenarios in a random order.
|
||||||
//
|
//
|
||||||
// This is especially helpful for detecting situations
|
// Randomizing scenario order is especially helpful for detecting
|
||||||
// where you have state leaking between scenarios, which
|
// situations where you have state leaking between scenarios, which can
|
||||||
// can cause flickering or fragile tests.
|
// cause flickering or fragile tests.
|
||||||
RandomOrder bool
|
//
|
||||||
|
// The default value of `0` means "do not randomize".
|
||||||
|
//
|
||||||
|
// The magic value of `-1` means "pick a random seed for me", the resulting
|
||||||
|
// seed will only be between `1-99999` for ease of specification.
|
||||||
|
RandomSeed int64
|
||||||
|
|
||||||
// Stops on the first failure
|
// Stops on the first failure
|
||||||
StopOnFailure bool
|
StopOnFailure bool
|
||||||
|
|
26
run.go
26
run.go
|
@ -13,7 +13,7 @@ import (
|
||||||
type initializer func(*Suite)
|
type initializer func(*Suite)
|
||||||
|
|
||||||
type runner struct {
|
type runner struct {
|
||||||
randomOrder bool
|
randomSeed int64
|
||||||
stopOnFailure bool
|
stopOnFailure bool
|
||||||
features []*feature
|
features []*feature
|
||||||
fmt Formatter
|
fmt Formatter
|
||||||
|
@ -33,7 +33,7 @@ func (r *runner) concurrent(rate int) (failed bool) {
|
||||||
}
|
}
|
||||||
suite := &Suite{
|
suite := &Suite{
|
||||||
fmt: r.fmt,
|
fmt: r.fmt,
|
||||||
randomOrder: r.randomOrder,
|
randomSeed: r.randomSeed,
|
||||||
stopOnFailure: r.stopOnFailure,
|
stopOnFailure: r.stopOnFailure,
|
||||||
features: []*feature{feat},
|
features: []*feature{feat},
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ func (r *runner) concurrent(rate int) (failed bool) {
|
||||||
func (r *runner) run() (failed bool) {
|
func (r *runner) run() (failed bool) {
|
||||||
suite := &Suite{
|
suite := &Suite{
|
||||||
fmt: r.fmt,
|
fmt: r.fmt,
|
||||||
randomOrder: r.randomOrder,
|
randomSeed: r.randomSeed,
|
||||||
stopOnFailure: r.stopOnFailure,
|
stopOnFailure: r.stopOnFailure,
|
||||||
features: r.features,
|
features: r.features,
|
||||||
}
|
}
|
||||||
|
@ -111,20 +111,26 @@ func RunWithOptions(suite string, contextInitializer func(suite *Suite), opt Opt
|
||||||
features, err := parseFeatures(opt.Tags, opt.Paths)
|
features, err := parseFeatures(opt.Tags, opt.Paths)
|
||||||
fatal(err)
|
fatal(err)
|
||||||
|
|
||||||
|
seed := opt.RandomSeed
|
||||||
|
if seed == -1 {
|
||||||
|
// if RandomSeed opt is -1, means pick a memorable rand seed as default
|
||||||
|
// the docStrings for Option specify this should be 1-99999 (same as ruby Cucumber)
|
||||||
|
r := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
|
||||||
|
seed = r.Int63n(99998) + 1
|
||||||
|
}
|
||||||
|
if seed != 0 {
|
||||||
|
// init global rand module (concurrent safe) with our seed
|
||||||
|
rand.Seed(seed)
|
||||||
|
}
|
||||||
|
|
||||||
r := runner{
|
r := runner{
|
||||||
fmt: formatter(suite, output),
|
fmt: formatter(suite, output),
|
||||||
initializer: contextInitializer,
|
initializer: contextInitializer,
|
||||||
features: features,
|
features: features,
|
||||||
randomOrder: opt.RandomOrder,
|
randomSeed: seed,
|
||||||
stopOnFailure: opt.StopOnFailure,
|
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
|
var failed bool
|
||||||
if opt.Concurrency > 1 {
|
if opt.Concurrency > 1 {
|
||||||
failed = r.concurrent(opt.Concurrency)
|
failed = r.concurrent(opt.Concurrency)
|
||||||
|
|
4
suite.go
4
suite.go
|
@ -50,7 +50,7 @@ type Suite struct {
|
||||||
fmt Formatter
|
fmt Formatter
|
||||||
|
|
||||||
failed bool
|
failed bool
|
||||||
randomOrder bool
|
randomSeed int64
|
||||||
stopOnFailure bool
|
stopOnFailure bool
|
||||||
|
|
||||||
// suite event handlers
|
// suite event handlers
|
||||||
|
@ -336,7 +336,7 @@ func (s *Suite) runFeature(f *feature) {
|
||||||
// make a local copy of the feature scenario defenitions,
|
// make a local copy of the feature scenario defenitions,
|
||||||
// then shuffle it if we are randomizing scenarios
|
// then shuffle it if we are randomizing scenarios
|
||||||
scenarios := make([]interface{}, len(f.ScenarioDefinitions))
|
scenarios := make([]interface{}, len(f.ScenarioDefinitions))
|
||||||
if s.randomOrder {
|
if s.randomSeed != 0 {
|
||||||
perm := rand.Perm(len(f.ScenarioDefinitions))
|
perm := rand.Perm(len(f.ScenarioDefinitions))
|
||||||
for i, v := range perm {
|
for i, v := range perm {
|
||||||
scenarios[v] = f.ScenarioDefinitions[i]
|
scenarios[v] = f.ScenarioDefinitions[i]
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче