diff --git a/README.md b/README.md index cc3149b..cf21b7a 100644 --- a/README.md +++ b/README.md @@ -206,7 +206,6 @@ installed. See the following example: package main import ( - "flag" "os" "testing" @@ -214,21 +213,13 @@ import ( ) func TestMain(m *testing.M) { - args := os.Args - // args for godog - os.Args = []string{ - args[0], - "-f", "progress", - "features", - } - - status := godog.Run(func(s *godog.Suite) { + status := godog.RunWithOptions(func(s *godog.Suite) { FeatureContext(s) + }, godog.Options{ + Format: "progress", + Paths: []string{"features"}, }) - os.Args = args - flag.Parse() - if st := m.Run(); st > status { status = st } diff --git a/cmd/godog/main.go b/cmd/godog/main.go index 1dab0b2..1904cc5 100644 --- a/cmd/godog/main.go +++ b/cmd/godog/main.go @@ -68,8 +68,10 @@ func main() { var tags, format, output string var concurrency int - flagSet := godog.FlagSet(&format, &tags, &defs, &sof, &noclr, &concurrency, &output) + flagSet := godog.FlagSet(&format, &tags, &defs, &sof, &noclr, &concurrency) flagSet.BoolVar(&vers, "version", false, "Show current version.") + flagSet.StringVar(&output, "o", "", "Build and output test runner executable to given target path.") + flagSet.StringVar(&output, "output", "", "Build and output test runner executable to given target path.") err := flagSet.Parse(os.Args[1:]) if err != nil { diff --git a/examples/godogs/godogs_test.go b/examples/godogs/godogs_test.go index 20546c3..130faab 100644 --- a/examples/godogs/godogs_test.go +++ b/examples/godogs/godogs_test.go @@ -2,7 +2,6 @@ package main import ( - "flag" "fmt" "os" "testing" @@ -11,21 +10,13 @@ import ( ) func TestMain(m *testing.M) { - args := os.Args - // args for godog - os.Args = []string{ - args[0], - "-f", "progress", - "features", - } - - status := godog.Run(func(s *godog.Suite) { + status := godog.RunWithOptions(func(s *godog.Suite) { FeatureContext(s) + }, godog.Options{ + Format: "progress", + Paths: []string{"features"}, }) - os.Args = args - flag.Parse() - if st := m.Run(); st > status { status = st } diff --git a/flags.go b/flags.go index bdcad34..6968726 100644 --- a/flags.go +++ b/flags.go @@ -23,11 +23,8 @@ var descTagsOption = "Filter scenarios by tags. Expression can be:\n" + s(4) + "- " + cl(`"@wip && ~@new"`, yellow) + ": run wip scenarios, but exclude new\n" + s(4) + "- " + cl(`"@wip,@undone"`, yellow) + ": run wip or undone scenarios" -var descOutputOption = "Output the temporary test runner executable:\n" + - s(4) + "- supply the name to give the executable " + cl("test_features.exe", yellow) + "\n" - // FlagSet allows to manage flags by external suite runner -func FlagSet(format, tags *string, defs, sof, noclr *bool, cr *int, output *string) *flag.FlagSet { +func FlagSet(format, tags *string, defs, sof, noclr *bool, cr *int) *flag.FlagSet { descFormatOption := "How to format tests output. Available formats:\n" for _, f := range formatters { descFormatOption += s(4) + "- " + cl(f.name, yellow) + ": " + f.description + "\n" @@ -45,8 +42,6 @@ func FlagSet(format, tags *string, defs, sof, noclr *bool, cr *int, output *stri set.BoolVar(defs, "d", false, "Print all available step definitions.") set.BoolVar(sof, "stop-on-failure", false, "Stop processing on first failed scenario.") set.BoolVar(noclr, "no-colors", false, "Disable ansi colors.") - set.StringVar(output, "output", "", descOutputOption) - set.StringVar(output, "o", "", descOutputOption) set.Usage = usage(set) return set } diff --git a/options.go b/options.go new file mode 100644 index 0000000..ab18b6c --- /dev/null +++ b/options.go @@ -0,0 +1,18 @@ +package godog + +// Options are suite run options +// flags are mapped to these options. +// +// It can also be used together with godog.RunWithOptions +// to run test suite from go source directly +// +// See the flags for more details +type Options struct { + ShowStepDefinitions bool + StopOnFailure bool + NoColors bool + Tags string + Format string + Concurrency int + Paths []string +} diff --git a/run.go b/run.go index 1e4628d..f2919ea 100644 --- a/run.go +++ b/run.go @@ -61,7 +61,58 @@ func (r *runner) run() (failed bool) { return suite.failed } +// RunWithOptions is same as Run function, except +// it uses Options provided in order to run the +// test suite without parsing flags +// +// This method is useful in case if you run +// godog in for example TestMain function together +// with go tests +func RunWithOptions(contextInitializer func(suite *Suite), opt Options) int { + if opt.ShowStepDefinitions { + s := &Suite{} + contextInitializer(s) + s.printStepDefinitions() + return 0 + } + + if len(opt.Paths) == 0 { + inf, err := os.Stat("features") + if err == nil && inf.IsDir() { + opt.Paths = []string{"features"} + } + } + + if opt.Concurrency > 1 && opt.Format != "progress" { + fatal(fmt.Errorf("when concurrency level is higher than 1, only progress format is supported")) + } + formatter, err := findFmt(opt.Format) + fatal(err) + + features, err := parseFeatures(opt.Tags, opt.Paths) + fatal(err) + + r := runner{ + fmt: formatter, + initializer: contextInitializer, + features: features, + stopOnFailure: opt.StopOnFailure, + } + + var failed bool + if opt.Concurrency > 1 { + failed = r.concurrent(opt.Concurrency) + } else { + failed = r.run() + } + if failed { + return 1 + } + return 0 +} + // Run creates and runs the feature suite. +// Reads all configuration options from flags. // uses contextInitializer to register contexts // // the concurrency option allows runner to @@ -73,52 +124,18 @@ func (r *runner) run() (failed bool) { // contextInitializer must be able to register // the step definitions and event handlers. func Run(contextInitializer func(suite *Suite)) int { - var defs, sof, noclr bool - var tags, format, output string - var concurrency int - flagSet := FlagSet(&format, &tags, &defs, &sof, &noclr, &concurrency, &output) + var opt Options + flagSet := FlagSet( + &opt.Format, + &opt.Tags, + &opt.ShowStepDefinitions, + &opt.StopOnFailure, + &opt.NoColors, + &opt.Concurrency, + ) err := flagSet.Parse(os.Args[1:]) fatal(err) + opt.Paths = flagSet.Args() - if defs { - s := &Suite{} - contextInitializer(s) - s.printStepDefinitions() - return 0 - } - - paths := flagSet.Args() - if len(paths) == 0 { - inf, err := os.Stat("features") - if err == nil && inf.IsDir() { - paths = []string{"features"} - } - } - - if concurrency > 1 && format != "progress" { - fatal(fmt.Errorf("when concurrency level is higher than 1, only progress format is supported")) - } - formatter, err := findFmt(format) - fatal(err) - - features, err := parseFeatures(tags, paths) - fatal(err) - - r := runner{ - fmt: formatter, - initializer: contextInitializer, - features: features, - stopOnFailure: sof, - } - - var failed bool - if concurrency > 1 { - failed = r.concurrent(concurrency) - } else { - failed = r.run() - } - if failed { - return 1 - } - return 0 + return RunWithOptions(contextInitializer, opt) }