prints random seed in formatter summary

Этот коммит содержится в:
gedi 2017-04-27 11:06:44 +03:00 коммит произвёл Matthew Rothenberg
родитель d2eb563953
коммит 201677e152
7 изменённых файлов: 70 добавлений и 53 удалений

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

@ -1,5 +1,9 @@
# Change LOG # Change LOG
**2017-04-27**
- added an option to randomize scenario execution order, so we could
ensure that scenarios do not depend on global state.
**2016-10-30** - **v0.6.0** **2016-10-30** - **v0.6.0**
- added experimental **events** format, this might be used for unified - added experimental **events** format, this might be used for unified
cucumber formats. But should be not adapted widely, since it is highly cucumber formats. But should be not adapted widely, since it is highly

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

@ -209,6 +209,7 @@ package main
import ( import (
"os" "os"
"testing" "testing"
"time"
"github.com/DATA-DOG/godog" "github.com/DATA-DOG/godog"
) )
@ -217,8 +218,9 @@ func TestMain(m *testing.M) {
status := godog.RunWithOptions("godogs", func(s *godog.Suite) { status := godog.RunWithOptions("godogs", func(s *godog.Suite) {
FeatureContext(s) FeatureContext(s)
}, godog.Options{ }, godog.Options{
Format: "progress", Format: "progress",
Paths: []string{"features"}, Paths: []string{"features"},
Randomize: time.Now().UTC().UnixNano(), // randomize scenario execution order
}) })
if st := m.Run(); st > status { if st := m.Run(); st > status {

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

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"os" "os"
"testing" "testing"
"time"
"github.com/DATA-DOG/godog" "github.com/DATA-DOG/godog"
) )
@ -13,8 +14,9 @@ func TestMain(m *testing.M) {
status := godog.RunWithOptions("godogs", func(s *godog.Suite) { status := godog.RunWithOptions("godogs", func(s *godog.Suite) {
FeatureContext(s) FeatureContext(s)
}, godog.Options{ }, godog.Options{
Format: "progress", Format: "progress",
Paths: []string{"features"}, Paths: []string{"features"},
Randomize: time.Now().UTC().UnixNano(), // randomize scenario execution order
}) })
if st := m.Run(); st > status { if st := m.Run(); st > status {

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

@ -4,7 +4,10 @@ import (
"flag" "flag"
"fmt" "fmt"
"io" "io"
"math/rand"
"strconv"
"strings" "strings"
"time"
"github.com/DATA-DOG/godog/colors" "github.com/DATA-DOG/godog/colors"
) )
@ -50,7 +53,7 @@ func FlagSet(opt *Options) *flag.FlagSet {
set.BoolVar(&opt.ShowStepDefinitions, "d", false, "Print all available step definitions.") set.BoolVar(&opt.ShowStepDefinitions, "d", false, "Print all available step definitions.")
set.BoolVar(&opt.StopOnFailure, "stop-on-failure", false, "Stop processing on first failed scenario.") set.BoolVar(&opt.StopOnFailure, "stop-on-failure", false, "Stop processing on first failed scenario.")
set.BoolVar(&opt.NoColors, "no-colors", false, "Disable ansi colors.") set.BoolVar(&opt.NoColors, "no-colors", false, "Disable ansi colors.")
set.Var(&opt.Randomize, "random", descRandomOption) set.Var(&randomSeed{&opt.Randomize}, "random", descRandomOption)
set.Usage = usage(set, opt.Output) set.Usage = usage(set, opt.Output)
return set return set
} }
@ -147,3 +150,42 @@ func usage(set *flag.FlagSet, w io.Writer) func() {
fmt.Fprintln(w, "") fmt.Fprintln(w, "")
} }
} }
// randomSeed implements `flag.Value`, see https://golang.org/pkg/flag/#Value
type randomSeed struct {
ref *int64
}
// Choose randomly assigns a convenient pseudo-random seed value.
// The resulting seed will be between `1-99999` for later ease of specification.
func (rs *randomSeed) choose() {
r := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
*rs.ref = r.Int63n(99998) + 1
}
func (rs *randomSeed) Set(s string) error {
if s == "true" {
rs.choose()
return nil
}
if s == "false" {
*rs.ref = 0
return nil
}
i, err := strconv.ParseInt(s, 10, 64)
*rs.ref = i
return err
}
func (rs randomSeed) String() string {
return strconv.FormatInt(*rs.ref, 10)
}
// If a Value has an IsBoolFlag() bool method returning true, the command-line
// parser makes -name equivalent to -name=true rather than using the next
// command-line argument.
func (rs *randomSeed) IsBoolFlag() bool {
return *rs.ref == 0
}

9
fmt.go
Просмотреть файл

@ -4,8 +4,10 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"os"
"reflect" "reflect"
"regexp" "regexp"
"strconv"
"strings" "strings"
"text/template" "text/template"
"time" "time"
@ -319,6 +321,13 @@ func (f *basefmt) Summary() {
} }
fmt.Fprintln(f.out, elapsed) fmt.Fprintln(f.out, elapsed)
// prints used randomization seed
seed, err := strconv.ParseInt(os.Getenv("GODOG_SEED"), 10, 64)
if err == nil && seed != 0 {
fmt.Fprintln(f.out, "")
fmt.Fprintln(f.out, "Randomized with seed:", colors.Yellow(seed))
}
if text := f.snippets(); text != "" { if text := f.snippets(); text != "" {
fmt.Fprintln(f.out, yellow("\nYou can implement step definitions for undefined steps with these snippets:")) fmt.Fprintln(f.out, yellow("\nYou can implement step definitions for undefined steps with these snippets:"))
fmt.Fprintln(f.out, yellow(text)) fmt.Fprintln(f.out, yellow(text))

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

@ -2,9 +2,6 @@ package godog
import ( import (
"io" "io"
"math/rand"
"strconv"
"time"
) )
// Options are suite run options // Options are suite run options
@ -33,7 +30,7 @@ type Options struct {
// Any other value will be used as the random seed for shuffling. Re-using the // Any other value will be used as the random seed for shuffling. Re-using the
// same seed will allow you to reproduce the shuffle order of a previous run // same seed will allow you to reproduce the shuffle order of a previous run
// to isolate an error condition. // to isolate an error condition.
Randomize randomSeed Randomize int64
// Stops on the first failure // Stops on the first failure
StopOnFailure bool StopOnFailure bool
@ -57,40 +54,3 @@ type Options struct {
// Where it should print formatter output // Where it should print formatter output
Output io.Writer Output io.Writer
} }
// randomSeed implements `flag.Value`, see https://golang.org/pkg/flag/#Value
type randomSeed int64
// Choose randomly assigns a convenient pseudo-random seed value.
// The resulting seed will be between `1-99999` for later ease of specification.
func (rs *randomSeed) Choose() {
r := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
*rs = randomSeed(r.Int63n(99998) + 1)
}
func (rs *randomSeed) Set(s string) error {
if s == "true" {
rs.Choose()
return nil
}
if s == "false" {
*rs = 0
return nil
}
i, err := strconv.ParseInt(s, 10, 64)
*rs = randomSeed(i)
return err
}
func (rs randomSeed) String() string {
return strconv.FormatInt(int64(rs), 10)
}
// If a Value has an IsBoolFlag() bool method returning true, the command-line
// parser makes -name equivalent to -name=true rather than using the next
// command-line argument.
func (rs *randomSeed) IsBoolFlag() bool {
return *rs == 0
}

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

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"strconv"
"github.com/DATA-DOG/godog/colors" "github.com/DATA-DOG/godog/colors"
) )
@ -109,20 +110,17 @@ 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)
// handle convenience condition where user specified `-1` in Options struct,
// asking us to choose the random value seed for them.
if opt.Randomize == -1 {
opt.Randomize.Choose()
}
r := runner{ r := runner{
fmt: formatter(suite, output), fmt: formatter(suite, output),
initializer: contextInitializer, initializer: contextInitializer,
features: features, features: features,
randomSeed: int64(opt.Randomize), randomSeed: opt.Randomize,
stopOnFailure: opt.StopOnFailure, stopOnFailure: opt.StopOnFailure,
} }
// store chosen seed in environment, so it could be seen in formatter summary report
os.Setenv("GODOG_SEED", strconv.FormatInt(r.randomSeed, 10))
var failed bool var failed bool
if opt.Concurrency > 1 { if opt.Concurrency > 1 {
failed = r.concurrent(opt.Concurrency) failed = r.concurrent(opt.Concurrency)