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
Этот коммит содержится в:
Viacheslav Poturaev 2022-08-31 10:17:00 +02:00 коммит произвёл GitHub
родитель 202882807b
коммит c35ea0b236
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 103 добавлений и 34 удалений

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

@ -10,6 +10,7 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
### 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))
- Removed deprecation of `godog.BindFlags` ([498](https://github.com/cucumber/godog/pull/498) - [vearutop](https://github.com/vearutop))
### 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))

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

@ -1,4 +1,3 @@
# file: $GOPATH/godogs/features/godogs.feature
Feature: eat godogs
In order to be happy
As a hungry gopher
@ -8,3 +7,8 @@ Feature: eat godogs
Given there are 12 godogs
When I eat 5
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 Обычный файл
Просмотреть файл

@ -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
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 (
"context"
"flag"
"fmt"
"os"
"testing"
"github.com/cucumber/godog"
"github.com/cucumber/godog/colors"
"github.com/spf13/pflag"
)
var opts = godog.Options{Output: colors.Colored(os.Stdout)}
func init() {
godog.BindCommandLineFlags("godog.", &opts)
godog.BindFlags("godog.", flag.CommandLine, &opts)
}
func TestMain(m *testing.M) {
pflag.Parse()
opts.Paths = pflag.Args()
func TestFeatures(t *testing.T) {
o := opts
o.TestingT = t
status := godog.TestSuite{
Name: "godogs",
Options: &o,
TestSuiteInitializer: InitializeTestSuite,
ScenarioInitializer: InitializeScenario,
Options: &opts,
}.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 {
@ -51,6 +68,10 @@ func thereShouldBeRemaining(remaining int) error {
return nil
}
func thereShouldBeNoneRemaining() error {
return thereShouldBeRemaining(0)
}
func InitializeTestSuite(ctx *godog.TestSuiteContext) {
ctx.BeforeSuite(func() { Godogs = 0 })
}
@ -64,4 +85,5 @@ func InitializeScenario(ctx *godog.ScenarioContext) {
ctx.Step(`^there are (\d+) godogs$`, thereAreGodogs)
ctx.Step(`^I eat (\d+)$`, iEat)
ctx.Step(`^there should be (\d+) remaining$`, thereShouldBeRemaining)
ctx.Step(`^there should be none remaining$`, thereShouldBeNoneRemaining)
}

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

@ -4,6 +4,7 @@ import (
"flag"
"fmt"
"io"
"sort"
"strconv"
"strings"
@ -18,7 +19,8 @@ var descFeaturesArgument = "Optional feature(s) to run. Can be:\n" +
s(4) + "- dir " + colors.Yellow("(features/)") + "\n" +
s(4) + "- feature " + colors.Yellow("(*.feature)") + "\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" +
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
// 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) {
set.Usage = usage(set, set.Output())
descFormatOption := "How to format tests output. Built-in formats:\n"
// @TODO: sort by name
for name, desc := range AvailableFormatters() {
descFormatOption += s(4) + "- " + colors.Yellow(name) + ": " + desc + "\n"
type fm struct {
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)
// 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.NoColors, prefix+"no-colors", defNoColors, "Disable ansi colors.")
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 {
@ -183,15 +208,7 @@ func usage(set *flag.FlagSet, w io.Writer) func() {
// --- GENERAL ---
fmt.Fprintln(w, colors.Yellow("Usage:"))
fmt.Fprintf(w, s(2)+"godog [options] [<features>]\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))
fmt.Fprintf(w, s(2)+"go test [options]\n\n")
// --- OPTIONS ---
fmt.Fprintln(w, colors.Yellow("Options:"))

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

@ -121,7 +121,9 @@ func TestBindFlagsShouldRespectOptDefaults(t *testing.T) {
Randomize: int64(7),
}
BindFlags("optDefaults.", flag.CommandLine, &opts)
flagSet := flag.FlagSet{}
BindFlags("optDefaults.", &flagSet, &opts)
if opts.Format != "progress" {
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
// in a map entry
FeatureContents []Feature
// ShowHelp enables suite to show CLI flags usage help and exit.
ShowHelp bool
}
type Feature struct {

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

@ -2,6 +2,7 @@ package godog
import (
"context"
"flag"
"fmt"
"go/build"
"io"
@ -309,10 +310,11 @@ type TestSuite struct {
// all configuration options from flags.
//
// The exit codes may vary from:
// 0 - success
// 1 - failed
// 2 - command line usage error
// 128 - or higher, os signal related error exit codes
//
// 0 - success
// 1 - failed
// 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
func (ts TestSuite) Run() int {
@ -323,6 +325,12 @@ func (ts TestSuite) Run() int {
return exitOptionError
}
}
if ts.Options.ShowHelp {
flag.CommandLine.Usage()
return 0
}
r := runner{testSuiteInitializer: ts.TestSuiteInitializer, scenarioInitializer: ts.ScenarioInitializer}
return runWithOptions(ts.Name, r, *ts.Options)
}