Remove deprecation from flags, update example to use CLI flags (#498)
* Remove deprecation from flags, update example to use CLI flags * Add comment to ShowHelp option * Fix test * Update CHANGELOG.md
Этот коммит содержится в:
родитель
202882807b
коммит
c35ea0b236
9 изменённых файлов: 103 добавлений и 34 удалений
|
@ -10,6 +10,7 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- README example is updated with `context.Context` and `go test` usage. ([477](https://github.com/cucumber/godog/pull/477) - [vearutop](https://github.com/vearutop))
|
- README example is updated with `context.Context` and `go test` usage. ([477](https://github.com/cucumber/godog/pull/477) - [vearutop](https://github.com/vearutop))
|
||||||
|
- Removed deprecation of `godog.BindFlags` ([498](https://github.com/cucumber/godog/pull/498) - [vearutop](https://github.com/vearutop))
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Fixed a bug which would ignore the context returned from a substep.([488](https://github.com/cucumber/godog/pull/488) - [wichert](https://github.com/wichert))
|
- Fixed a bug which would ignore the context returned from a substep.([488](https://github.com/cucumber/godog/pull/488) - [wichert](https://github.com/wichert))
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# file: $GOPATH/godogs/features/godogs.feature
|
|
||||||
Feature: eat godogs
|
Feature: eat godogs
|
||||||
In order to be happy
|
In order to be happy
|
||||||
As a hungry gopher
|
As a hungry gopher
|
||||||
|
@ -8,3 +7,8 @@ Feature: eat godogs
|
||||||
Given there are 12 godogs
|
Given there are 12 godogs
|
||||||
When I eat 5
|
When I eat 5
|
||||||
Then there should be 7 remaining
|
Then there should be 7 remaining
|
||||||
|
|
||||||
|
Scenario: Eat 12 out of 12
|
||||||
|
Given there are 12 godogs
|
||||||
|
When I eat 12
|
||||||
|
Then there should be none remaining
|
||||||
|
|
14
_examples/godogs/features/nodogs.feature
Обычный файл
14
_examples/godogs/features/nodogs.feature
Обычный файл
|
@ -0,0 +1,14 @@
|
||||||
|
Feature: do not eat godogs
|
||||||
|
In order to be fit
|
||||||
|
As a well-fed gopher
|
||||||
|
I need to be able to avoid godogs
|
||||||
|
|
||||||
|
Scenario: Eat 0 out of 12
|
||||||
|
Given there are 12 godogs
|
||||||
|
When I eat 0
|
||||||
|
Then there should be 12 remaining
|
||||||
|
|
||||||
|
Scenario: Eat 0 out of 0
|
||||||
|
Given there are 0 godogs
|
||||||
|
When I eat 0
|
||||||
|
Then there should be none remaining
|
|
@ -1,6 +1,4 @@
|
||||||
package main
|
package godogs
|
||||||
|
|
||||||
// Godogs available to eat
|
// Godogs available to eat.
|
||||||
var Godogs int
|
var Godogs int
|
||||||
|
|
||||||
func main() { /* usual main func */ }
|
|
||||||
|
|
|
@ -1,34 +1,51 @@
|
||||||
package main
|
package godogs
|
||||||
|
|
||||||
|
// This example shows how to set up test suite runner with Go subtests and godog command line parameters.
|
||||||
|
// Sample commands:
|
||||||
|
// * run all scenarios from default directory (features): go test -test.run "^TestFeatures/"
|
||||||
|
// * run all scenarios and list subtest names: go test -test.v -test.run "^TestFeatures/"
|
||||||
|
// * run all scenarios from one feature file: go test -test.v -godog.paths features/nodogs.feature -test.run "^TestFeatures/"
|
||||||
|
// * run all scenarios from multiple feature files: go test -test.v -godog.paths features/nodogs.feature,features/godogs.feature -test.run "^TestFeatures/"
|
||||||
|
// * run single scenario as a subtest: go test -test.v -test.run "^TestFeatures/Eat_5_out_of_12$"
|
||||||
|
// * show usage help: go test -godog.help
|
||||||
|
// * show usage help if there were other test files in directory: go test -godog.help godogs_test.go
|
||||||
|
// * run scenarios with multiple formatters: go test -test.v -godog.format cucumber:cuc.json,pretty -test.run "^TestFeatures/"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/cucumber/godog"
|
"github.com/cucumber/godog"
|
||||||
"github.com/cucumber/godog/colors"
|
"github.com/cucumber/godog/colors"
|
||||||
"github.com/spf13/pflag"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var opts = godog.Options{Output: colors.Colored(os.Stdout)}
|
var opts = godog.Options{Output: colors.Colored(os.Stdout)}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
godog.BindCommandLineFlags("godog.", &opts)
|
godog.BindFlags("godog.", flag.CommandLine, &opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestFeatures(t *testing.T) {
|
||||||
pflag.Parse()
|
o := opts
|
||||||
opts.Paths = pflag.Args()
|
o.TestingT = t
|
||||||
|
|
||||||
status := godog.TestSuite{
|
status := godog.TestSuite{
|
||||||
Name: "godogs",
|
Name: "godogs",
|
||||||
|
Options: &o,
|
||||||
TestSuiteInitializer: InitializeTestSuite,
|
TestSuiteInitializer: InitializeTestSuite,
|
||||||
ScenarioInitializer: InitializeScenario,
|
ScenarioInitializer: InitializeScenario,
|
||||||
Options: &opts,
|
|
||||||
}.Run()
|
}.Run()
|
||||||
|
|
||||||
os.Exit(status)
|
if status == 2 {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != 0 {
|
||||||
|
t.Fatalf("zero status code expected, %d received", status)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func thereAreGodogs(available int) error {
|
func thereAreGodogs(available int) error {
|
||||||
|
@ -51,6 +68,10 @@ func thereShouldBeRemaining(remaining int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func thereShouldBeNoneRemaining() error {
|
||||||
|
return thereShouldBeRemaining(0)
|
||||||
|
}
|
||||||
|
|
||||||
func InitializeTestSuite(ctx *godog.TestSuiteContext) {
|
func InitializeTestSuite(ctx *godog.TestSuiteContext) {
|
||||||
ctx.BeforeSuite(func() { Godogs = 0 })
|
ctx.BeforeSuite(func() { Godogs = 0 })
|
||||||
}
|
}
|
||||||
|
@ -64,4 +85,5 @@ func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||||
ctx.Step(`^there are (\d+) godogs$`, thereAreGodogs)
|
ctx.Step(`^there are (\d+) godogs$`, thereAreGodogs)
|
||||||
ctx.Step(`^I eat (\d+)$`, iEat)
|
ctx.Step(`^I eat (\d+)$`, iEat)
|
||||||
ctx.Step(`^there should be (\d+) remaining$`, thereShouldBeRemaining)
|
ctx.Step(`^there should be (\d+) remaining$`, thereShouldBeRemaining)
|
||||||
|
ctx.Step(`^there should be none remaining$`, thereShouldBeNoneRemaining)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -18,7 +19,8 @@ var descFeaturesArgument = "Optional feature(s) to run. Can be:\n" +
|
||||||
s(4) + "- dir " + colors.Yellow("(features/)") + "\n" +
|
s(4) + "- dir " + colors.Yellow("(features/)") + "\n" +
|
||||||
s(4) + "- feature " + colors.Yellow("(*.feature)") + "\n" +
|
s(4) + "- feature " + colors.Yellow("(*.feature)") + "\n" +
|
||||||
s(4) + "- scenario at specific line " + colors.Yellow("(*.feature:10)") + "\n" +
|
s(4) + "- scenario at specific line " + colors.Yellow("(*.feature:10)") + "\n" +
|
||||||
"If no feature paths are listed, suite tries " + colors.Yellow("features") + " path by default.\n"
|
"If no feature paths are listed, suite tries " + colors.Yellow("features") + " path by default.\n" +
|
||||||
|
"Multiple comma-separated values can be provided.\n"
|
||||||
|
|
||||||
var descConcurrencyOption = "Run the test suite with concurrency level:\n" +
|
var descConcurrencyOption = "Run the test suite with concurrency level:\n" +
|
||||||
s(4) + "- " + colors.Yellow(`= 1`) + ": supports all types of formats.\n" +
|
s(4) + "- " + colors.Yellow(`= 1`) + ": supports all types of formats.\n" +
|
||||||
|
@ -48,15 +50,30 @@ func FlagSet(opt *Options) *flag.FlagSet {
|
||||||
|
|
||||||
// BindFlags binds godog flags to given flag set prefixed
|
// BindFlags binds godog flags to given flag set prefixed
|
||||||
// by given prefix, without overriding usage
|
// by given prefix, without overriding usage
|
||||||
//
|
|
||||||
// Deprecated: Use BindCommandLineFlags(prefix, &opts)
|
|
||||||
// instead of BindFlags(prefix, flag.CommandLine, &opts)
|
|
||||||
func BindFlags(prefix string, set *flag.FlagSet, opt *Options) {
|
func BindFlags(prefix string, set *flag.FlagSet, opt *Options) {
|
||||||
|
set.Usage = usage(set, set.Output())
|
||||||
|
|
||||||
descFormatOption := "How to format tests output. Built-in formats:\n"
|
descFormatOption := "How to format tests output. Built-in formats:\n"
|
||||||
// @TODO: sort by name
|
|
||||||
for name, desc := range AvailableFormatters() {
|
type fm struct {
|
||||||
descFormatOption += s(4) + "- " + colors.Yellow(name) + ": " + desc + "\n"
|
name string
|
||||||
|
desc string
|
||||||
}
|
}
|
||||||
|
var fms []fm
|
||||||
|
for name, desc := range AvailableFormatters() {
|
||||||
|
fms = append(fms, fm{
|
||||||
|
name: name,
|
||||||
|
desc: desc,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
sort.Slice(fms, func(i, j int) bool {
|
||||||
|
return fms[i].name < fms[j].name
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, fm := range fms {
|
||||||
|
descFormatOption += s(4) + "- " + colors.Yellow(fm.name) + ": " + fm.desc + "\n"
|
||||||
|
}
|
||||||
|
|
||||||
descFormatOption = strings.TrimSpace(descFormatOption)
|
descFormatOption = strings.TrimSpace(descFormatOption)
|
||||||
|
|
||||||
// override flag defaults if any corresponding properties were supplied on the incoming `opt`
|
// override flag defaults if any corresponding properties were supplied on the incoming `opt`
|
||||||
|
@ -107,6 +124,14 @@ func BindFlags(prefix string, set *flag.FlagSet, opt *Options) {
|
||||||
set.BoolVar(&opt.Strict, prefix+"strict", defStrict, "Fail suite when there are pending or undefined steps.")
|
set.BoolVar(&opt.Strict, prefix+"strict", defStrict, "Fail suite when there are pending or undefined steps.")
|
||||||
set.BoolVar(&opt.NoColors, prefix+"no-colors", defNoColors, "Disable ansi colors.")
|
set.BoolVar(&opt.NoColors, prefix+"no-colors", defNoColors, "Disable ansi colors.")
|
||||||
set.Var(&randomSeed{&opt.Randomize}, prefix+"random", descRandomOption)
|
set.Var(&randomSeed{&opt.Randomize}, prefix+"random", descRandomOption)
|
||||||
|
set.BoolVar(&opt.ShowHelp, "godog.help", false, "Show usage help.")
|
||||||
|
set.Func(prefix+"paths", descFeaturesArgument, func(paths string) error {
|
||||||
|
if paths != "" {
|
||||||
|
opt.Paths = strings.Split(paths, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type flagged struct {
|
type flagged struct {
|
||||||
|
@ -183,15 +208,7 @@ func usage(set *flag.FlagSet, w io.Writer) func() {
|
||||||
|
|
||||||
// --- GENERAL ---
|
// --- GENERAL ---
|
||||||
fmt.Fprintln(w, colors.Yellow("Usage:"))
|
fmt.Fprintln(w, colors.Yellow("Usage:"))
|
||||||
fmt.Fprintf(w, s(2)+"godog [options] [<features>]\n\n")
|
fmt.Fprintf(w, s(2)+"go test [options]\n\n")
|
||||||
// description
|
|
||||||
fmt.Fprintln(w, "Builds a test package and runs given feature files.")
|
|
||||||
fmt.Fprintf(w, "Command should be run from the directory of tested package and contain buildable go source.\n\n")
|
|
||||||
|
|
||||||
// --- ARGUMENTS ---
|
|
||||||
fmt.Fprintln(w, colors.Yellow("Arguments:"))
|
|
||||||
// --> features
|
|
||||||
fmt.Fprintln(w, opt("features", descFeaturesArgument))
|
|
||||||
|
|
||||||
// --- OPTIONS ---
|
// --- OPTIONS ---
|
||||||
fmt.Fprintln(w, colors.Yellow("Options:"))
|
fmt.Fprintln(w, colors.Yellow("Options:"))
|
|
@ -121,7 +121,9 @@ func TestBindFlagsShouldRespectOptDefaults(t *testing.T) {
|
||||||
Randomize: int64(7),
|
Randomize: int64(7),
|
||||||
}
|
}
|
||||||
|
|
||||||
BindFlags("optDefaults.", flag.CommandLine, &opts)
|
flagSet := flag.FlagSet{}
|
||||||
|
|
||||||
|
BindFlags("optDefaults.", &flagSet, &opts)
|
||||||
|
|
||||||
if opts.Format != "progress" {
|
if opts.Format != "progress" {
|
||||||
t.Fatalf("expected Format: progress, but it was: %s", opts.Format)
|
t.Fatalf("expected Format: progress, but it was: %s", opts.Format)
|
|
@ -69,6 +69,9 @@ type Options struct {
|
||||||
// where the contents of each feature is stored as a byte slice
|
// where the contents of each feature is stored as a byte slice
|
||||||
// in a map entry
|
// in a map entry
|
||||||
FeatureContents []Feature
|
FeatureContents []Feature
|
||||||
|
|
||||||
|
// ShowHelp enables suite to show CLI flags usage help and exit.
|
||||||
|
ShowHelp bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Feature struct {
|
type Feature struct {
|
||||||
|
|
16
run.go
16
run.go
|
@ -2,6 +2,7 @@ package godog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/build"
|
"go/build"
|
||||||
"io"
|
"io"
|
||||||
|
@ -309,10 +310,11 @@ type TestSuite struct {
|
||||||
// all configuration options from flags.
|
// all configuration options from flags.
|
||||||
//
|
//
|
||||||
// The exit codes may vary from:
|
// The exit codes may vary from:
|
||||||
// 0 - success
|
//
|
||||||
// 1 - failed
|
// 0 - success
|
||||||
// 2 - command line usage error
|
// 1 - failed
|
||||||
// 128 - or higher, os signal related error exit codes
|
// 2 - command line usage error
|
||||||
|
// 128 - or higher, os signal related error exit codes
|
||||||
//
|
//
|
||||||
// If there are flag related errors they will be directed to os.Stderr
|
// If there are flag related errors they will be directed to os.Stderr
|
||||||
func (ts TestSuite) Run() int {
|
func (ts TestSuite) Run() int {
|
||||||
|
@ -323,6 +325,12 @@ func (ts TestSuite) Run() int {
|
||||||
return exitOptionError
|
return exitOptionError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ts.Options.ShowHelp {
|
||||||
|
flag.CommandLine.Usage()
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
r := runner{testSuiteInitializer: ts.TestSuiteInitializer, scenarioInitializer: ts.ScenarioInitializer}
|
r := runner{testSuiteInitializer: ts.TestSuiteInitializer, scenarioInitializer: ts.ScenarioInitializer}
|
||||||
return runWithOptions(ts.Name, r, *ts.Options)
|
return runWithOptions(ts.Name, r, *ts.Options)
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче