godog

package module
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2024 License: MIT Imports: 33 Imported by: 480

README

Build Status PkgGoDev codecov pull requests issues

Godog

Godog logo

The API is likely to change a few times before we reach 1.0.0

Please read the full README, you may find it very useful. And do not forget to peek into the Release Notes and the CHANGELOG from time to time.

Package godog is the official Cucumber BDD framework for Golang, it merges specification and test documentation into one cohesive whole, using Gherkin formatted scenarios in the format of Given, When, Then.

The project was inspired by behat and cucumber.

Why Godog/Cucumber

A single source of truth

Godog merges specification and test documentation into one cohesive whole.

Living documentation

Because they're automatically tested by Godog, your specifications are always bang up-to-date.

Focus on the customer

Business and IT don't always understand each other. Godog's executable specifications encourage closer collaboration, helping teams keep the business goal in mind at all times.

Less rework

When automated testing is this much fun, teams can easily protect themselves from costly regressions.

Read more

Contributions

Godog is a community driven Open Source Project within the Cucumber organization. We welcome contributions from everyone, and we're ready to support you if you have the enthusiasm to contribute.

See the contributing guide for more detail on how to get started.

See the releasing guide for release flow details.

Getting help

We have a community Discord where you can chat with other users, developers, and BDD practitioners.

Examples

You can find a few examples here.

Note that if you want to execute any of the examples and have the Git repository checked out in the $GOPATH, you need to use: GO111MODULE=off. Issue for reference.

Godogs

The following example can be found here.

Step 1 - Setup a go module

Create a new go module named godogs in your go workspace by running mkdir godogs

From now on, use godogs as your working directory by running cd godogs

Initiate the go module inside the godogs directory by running go mod init godogs

Step 2 - Create gherkin feature

Imagine we have a godog cart to serve godogs for lunch.

First of all, we describe our feature in plain text:

Feature: eat godogs
  In order to be happy
  As a hungry gopher
  I need to be able to eat godogs

  Scenario: Eat 5 out of 12
    Given there are 12 godogs
    When I eat 5
    Then there should be 7 remaining

Run vim features/godogs.feature and add the text above into the vim editor and save the file.

Step 3 - Create godog step definitions

NOTE: Same as go test, godog respects package level isolation. All your step definitions should be in your tested package root directory. In this case: godogs.

Create and copy the step definitions below into a new file by running vim godogs_test.go:

package main

import "github.com/cucumber/godog"

func iEat(arg1 int) error {
        return godog.ErrPending
}

func thereAreGodogs(arg1 int) error {
        return godog.ErrPending
}

func thereShouldBeRemaining(arg1 int) error {
        return godog.ErrPending
}

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)
}

Alternatively, you can also specify the keyword (Given, When, Then...) when creating the step definitions:

func InitializeScenario(ctx *godog.ScenarioContext) {
        ctx.Given(`^there are (\d+) godogs$`, thereAreGodogs)
        ctx.When(`^I eat (\d+)$`, iEat)
        ctx.Then(`^there should be (\d+) remaining$`, thereShouldBeRemaining)
}

Our module should now look like this:

godogs
- features
  - godogs.feature
- go.mod
- go.sum
- godogs_test.go

Run go test in the godogs directory to run the steps you have defined. You should now see that the scenario runs with a warning stating there are no tests to run.

testing: warning: no tests to run
PASS
ok      godogs  0.225s

By adding some logic to these steps, you will be able to thoroughly test the feature you just defined.

Step 4 - Create the main program to test

Let's keep it simple by only requiring an amount of godogs for now.

Create and copy the code below into a new file by running vim godogs.go

package main

// Godogs available to eat
var Godogs int

func main() { /* usual main func */ }

Our module should now look like this:

godogs
- features
  - godogs.feature
- go.mod
- go.sum
- godogs.go
- godogs_test.go
Step 5 - Add some logic to the step definitions

Now lets implement our step definitions to test our feature requirements.

Replace the contents of godogs_test.go with the code below by running vim godogs_test.go.

package main

import (
  "context"
  "errors"
  "fmt"
  "testing"

  "github.com/cucumber/godog"
)

// godogsCtxKey is the key used to store the available godogs in the context.Context.
type godogsCtxKey struct{}

func thereAreGodogs(ctx context.Context, available int) (context.Context, error) {
  return context.WithValue(ctx, godogsCtxKey{}, available), nil
}

func iEat(ctx context.Context, num int) (context.Context, error) {
  available, ok := ctx.Value(godogsCtxKey{}).(int)
  if !ok {
    return ctx, errors.New("there are no godogs available")
  }

  if available < num {
    return ctx, fmt.Errorf("you cannot eat %d godogs, there are %d available", num, available)
  }

  available -= num

  return context.WithValue(ctx, godogsCtxKey{}, available), nil
}

func thereShouldBeRemaining(ctx context.Context, remaining int) error {
  available, ok := ctx.Value(godogsCtxKey{}).(int)
  if !ok {
    return errors.New("there are no godogs available")
  }

  if available != remaining {
    return fmt.Errorf("expected %d godogs to be remaining, but there is %d", remaining, available)
  }

  return nil
}

func TestFeatures(t *testing.T) {
  suite := godog.TestSuite{
    ScenarioInitializer: InitializeScenario,
    Options: &godog.Options{
      Format:   "pretty",
      Paths:    []string{"features"},
      TestingT: t, // Testing instance that will run subtests.
    },
  }

  if suite.Run() != 0 {
    t.Fatal("non-zero status returned, failed to run feature tests")
  }
}

func InitializeScenario(sc *godog.ScenarioContext) {
  sc.Step(`^there are (\d+) godogs$`, thereAreGodogs)
  sc.Step(`^I eat (\d+)$`, iEat)
  sc.Step(`^there should be (\d+) remaining$`, thereShouldBeRemaining)
}

In this example, we are using context.Context to pass the state between the steps. Every scenario starts with an empty context and then steps and hooks can add relevant information to it. Instrumented context is chained through the steps and hooks and is safe to use when multiple scenarios are running concurrently.

When you run godog again with go test -v godogs_test.go, you should see a passing run:

=== RUN   TestFeatures
Feature: eat godogs
  In order to be happy
  As a hungry gopher
  I need to be able to eat godogs
=== RUN   TestFeatures/Eat_5_out_of_12

  Scenario: Eat 5 out of 12          # features/godogs.feature:6
    Given there are 12 godogs        # godog_test.go:15 -> command-line-arguments.thereAreGodogs
    When I eat 5                     # godog_test.go:19 -> command-line-arguments.iEat
    Then there should be 7 remaining # godog_test.go:34 -> command-line-arguments.thereShouldBeRemaining

1 scenarios (1 passed)
3 steps (3 passed)
279.917µs
--- PASS: TestFeatures (0.00s)
    --- PASS: TestFeatures/Eat_5_out_of_12 (0.00s)
PASS
ok      command-line-arguments  0.164s

You may hook to ScenarioContext Before event in order to reset or pre-seed the application state before each scenario. You may hook into more events, like sc.StepContext() After to print all state in case of an error. Or BeforeSuite to prepare a database.

By now, you should have figured out, how to use godog. Another piece of advice is to make steps orthogonal, small and simple to read for a user. Whether the user is a dumb website user or an API developer, who may understand a little more technical context - it should target that user.

When steps are orthogonal and small, you can combine them just like you do with Unix tools. Look how to simplify or remove ones, which can be composed.

TestFeatures acts as a regular Go test, so you can leverage your IDE facilities to run and debug it.

Attachments

An example showing how to make attachments (aka embeddings) to the results is shown in _examples/attachments

Code of Conduct

Everyone interacting in this codebase and issue tracker is expected to follow the Cucumber code of conduct.

References and Tutorials

Documentation

See pkg documentation for general API details. See Circle Config for supported go versions. See godog -h for general command options.

See implementation examples:

FAQ

Running Godog with go test

You may integrate running godog in your go test command.

Subtests of *testing.T

You can run test suite using go Subtests. In this case it is not necessary to have godog command installed. See the following example.

package main_test

import (
	"testing"

	"github.com/cucumber/godog"
)

func TestFeatures(t *testing.T) {
  suite := godog.TestSuite{
    ScenarioInitializer: func(s *godog.ScenarioContext) {
      // Add step definitions here.
    },
    Options: &godog.Options{
      Format:   "pretty",
      Paths:    []string{"features"},
      TestingT: t, // Testing instance that will run subtests.
    },
  }

  if suite.Run() != 0 {
    t.Fatal("non-zero status returned, failed to run feature tests")
  }
}

Then you can run suite.

go test -test.v -test.run ^TestFeatures$

Or a particular scenario.

go test -test.v -test.run ^TestFeatures$/^my_scenario$
TestMain

You can run test suite using go TestMain func available since go 1.4. In this case it is not necessary to have godog command installed. See the following examples.

The following example binds godog flags with specified prefix godog in order to prevent flag collisions.

package main

import (
	"os"
	"testing"

	"github.com/cucumber/godog"
	"github.com/cucumber/godog/colors"
	"github.com/spf13/pflag" // godog v0.11.0 and later
)

var opts = godog.Options{
	Output: colors.Colored(os.Stdout),
	Format: "progress", // can define default values
}

func init() {
	godog.BindFlags("godog.", pflag.CommandLine, &opts) // godog v0.10.0 and earlier
	godog.BindCommandLineFlags("godog.", &opts)        // godog v0.11.0 and later
}

func TestMain(m *testing.M) {
	pflag.Parse()
	opts.Paths = pflag.Args()

	status := godog.TestSuite{
		Name: "godogs",
		TestSuiteInitializer: InitializeTestSuite,
		ScenarioInitializer:  InitializeScenario,
		Options: &opts,
	}.Run()

	// Optional: Run `testing` package's logic besides godog.
	if st := m.Run(); st > status {
		status = st
	}

	os.Exit(status)
}

Then you may run tests with by specifying flags in order to filter features.

go test -v --godog.random --godog.tags=wip
go test -v --godog.format=pretty --godog.random -race -coverprofile=coverage.txt -covermode=atomic

The following example does not bind godog flags, instead manually configuring needed options.

func TestMain(m *testing.M) {
	opts := godog.Options{
		Format:    "progress",
		Paths:     []string{"features"},
		Randomize: time.Now().UTC().UnixNano(), // randomize scenario execution order
	}

	status := godog.TestSuite{
		Name: "godogs",
		TestSuiteInitializer: InitializeTestSuite,
		ScenarioInitializer:  InitializeScenario,
		Options: &opts,
	}.Run()

	// Optional: Run `testing` package's logic besides godog.
	if st := m.Run(); st > status {
		status = st
	}

	os.Exit(status)
}

You can even go one step further and reuse go test flags, like verbose mode in order to switch godog format. See the following example:

func TestMain(m *testing.M) {
	format := "progress"
	for _, arg := range os.Args[1:] {
		if arg == "-test.v=true" { // go test transforms -v option
			format = "pretty"
			break
		}
	}

	opts := godog.Options{
		Format: format,
		Paths:     []string{"features"},
	}

	status := godog.TestSuite{
		Name: "godogs",
		TestSuiteInitializer: InitializeTestSuite,
		ScenarioInitializer:  InitializeScenario,
		Options: &opts,
	}.Run()

	// Optional: Run `testing` package's logic besides godog.
	if st := m.Run(); st > status {
		status = st
	}

	os.Exit(status)
}

Now when running go test -v it will use pretty format.

Tags

If you want to filter scenarios by tags, you can use the -t=<expression> or --tags=<expression> where <expression> is one of the following:

  • @wip - run all scenarios with wip tag
  • ~@wip - exclude all scenarios with wip tag
  • @wip && ~@new - run wip scenarios, but exclude new
  • @wip,@undone - run wip or undone scenarios
Using assertion packages like testify with Godog

A more extensive example can be found here.

func thereShouldBeRemaining(ctx context.Context, remaining int) error {
	assert.Equal(
    godog.T(ctx), Godogs, remaining, 
    "Expected %d godogs to be remaining, but there is %d", remaining, Godogs,
  )
	return nil
}
Embeds

If you're looking to compile your test binary in advance of running, you can compile the feature files into the binary via go:embed:


//go:embed features/*
var features embed.FS

var opts = godog.Options{
	Paths: []string{"features"},
	FS:    features,
}

Now, the test binary can be compiled with all feature files embedded, and can be ran independently from the feature files:

> go test -c ./test/integration/integration_test.go
> mv integration.test /some/random/dir
> cd /some/random/dir
> ./integration.test

NOTE: godog.Options.FS is as fs.FS, so custom filesystem loaders can be used.

CLI Mode

NOTE: The godog CLI has been deprecated. It is recommended to use go test instead.

Another way to use godog is to run it in CLI mode.

In this mode godog CLI will use go under the hood to compile and run your test suite.

Godog does not intervene with the standard go test command behavior. You can leverage both frameworks to functionally test your application while maintaining all test related source code in _test.go files.

Godog acts similar compared to go test command, by using go compiler and linker tool in order to produce test executable. Godog contexts need to be exported the same way as Test functions for go tests. Note, that if you use godog command tool, it will use go executable to determine compiler and linker.

Install
go install github.com/cucumber/godog/cmd/godog@latest

Adding @v0.12.0 will install v0.12.0 specifically instead of master.

With go version prior to 1.17, use go get github.com/cucumber/godog/cmd/godog@v0.12.0. Running within the $GOPATH, you would also need to set GO111MODULE=on, like this:

GO111MODULE=on go get github.com/cucumber/godog/cmd/godog@v0.12.0
Configure common options for godog CLI

There are no global options or configuration files. Alias your common or project based commands: alias godog-wip="godog --format=progress --tags=@wip"

Concurrency

When concurrency is configured in options, godog will execute the scenarios concurrently, which is supported by all supplied formatters.

In order to support concurrency well, you should reset the state and isolate each scenario. They should not share any state. It is suggested to run the suite concurrently in order to make sure there is no state corruption or race conditions in the application.

It is also useful to randomize the order of scenario execution, which you can now do with --random command option or godog.Options.Randomize setting.

Building your own custom formatter

A simple example can be found here.

License

Godog and Gherkin are licensed under the MIT and developed as a part of the cucumber project

Documentation

Overview

Package godog is the official Cucumber BDD framework for Golang, it merges specification and test documentation into one cohesive whole.

Godog does not intervene with the standard "go test" command and it's behavior. You can leverage both frameworks to functionally test your application while maintaining all test related source code in *_test.go files.

Godog acts similar compared to go test command. It uses go compiler and linker tool in order to produce test executable. Godog contexts needs to be exported same as Test functions for go test.

For example, imagine you're about to create the famous UNIX ls command. Before you begin, you describe how the feature should work, see the example below..

Example:

Feature: ls
  In order to see the directory structure
  As a UNIX user
  I need to be able to list the current directory's contents

  Scenario:
	Given I am in a directory "test"
	And I have a file named "foo"
	And I have a file named "bar"
	When I run ls
	Then I should get output:
	  """
	  bar
	  foo
	  """

Now, wouldn't it be cool if something could read this sentence and use it to actually run a test against the ls command? Hey, that's exactly what this package does! As you'll see, Godog is easy to learn, quick to use, and will put the fun back into tests.

Godog was inspired by Behat and Cucumber the above description is taken from it's documentation.

Index

Examples

Constants

View Source
const (
	// StepPassed indicates step that passed.
	StepPassed StepResultStatus = models.Passed
	// StepFailed indicates step that failed.
	StepFailed = models.Failed
	// StepSkipped indicates step that was skipped.
	StepSkipped = models.Skipped
	// StepUndefined indicates undefined step.
	StepUndefined = models.Undefined
	// StepPending indicates step with pending implementation.
	StepPending = models.Pending
	// StepAmbiguous indicates step text matches more than one step def
	StepAmbiguous = models.Ambiguous
)

Variables

View Source
var ErrAmbiguous = fmt.Errorf("ambiguous step definition")

more than one regex matched the step text

View Source
var ErrPending = fmt.Errorf("step implementation is pending")

ErrPending should be returned by step definition if step implementation is pending

View Source
var ErrSkip = fmt.Errorf("skipped")

ErrSkip should be returned by step definition or a hook if scenario and further steps are to be skipped.

View Source
var ErrUndefined = fmt.Errorf("step is undefined")

ErrUndefined is returned in case if step definition was not found

View Source
var Version = "v0.0.0-dev"

Version of package - based on Semantic Versioning 2.0.0 http://semver.org/

Functions

func Attach added in v0.15.0

func Attach(ctx context.Context, attachments ...Attachment) context.Context

func AvailableFormatters

func AvailableFormatters() map[string]string

AvailableFormatters gives a map of all formatters registered with their name as key and description as value

func BindCommandLineFlags added in v0.11.0

func BindCommandLineFlags(prefix string, opts *Options)

BindCommandLineFlags binds godog flags to given flag set prefixed by given prefix, without overriding usage

func BindFlags added in v0.7.9

func BindFlags(prefix string, set *flag.FlagSet, opt *Options)

BindFlags binds godog flags to given flag set prefixed by given prefix, without overriding usage

func Build

func Build(bin string) error

Build creates a test package like go test command at given target path. If there are no go files in tested directory, then it simply builds a godog executable to scan features.

If there are go test files, it first builds a test package with standard go test command.

Finally, it generates godog suite executable which registers exported godog contexts from the test files of tested package.

Returns the path to generated executable

func FlagSet deprecated

func FlagSet(opt *Options) *flag.FlagSet

FlagSet allows to manage flags by external suite runner builds flag.FlagSet with godog flags binded

Deprecated:

func Format

func Format(name, description string, f FormatterFunc)

Format registers a feature suite output formatter by given name, description and FormatterFunc constructor function, to initialize formatter with the output recorder.

func Log added in v0.14.1

func Log(ctx context.Context, args ...interface{})

Log will log test output. If called in the context of a test and testing.T has been registered, this will log using the step's testing.T, else it will simply log to stdout.

func Logf added in v0.14.1

func Logf(ctx context.Context, format string, args ...interface{})

Logf will log test output. If called in the context of a test and testing.T has been registered, this will log using the step's testing.T, else it will simply log to stdout.

func LoggedMessages added in v0.14.1

func LoggedMessages(ctx context.Context) []string

LoggedMessages returns an array of any logged messages that have been recorded during the test through calls to godog.Log / godog.Logf or via operations against godog.T(ctx)

Types

type AfterScenarioHook added in v0.12.0

type AfterScenarioHook func(ctx context.Context, sc *Scenario, err error) (context.Context, error)

AfterScenarioHook defines a hook after scenario.

type AfterStepHook added in v0.12.0

type AfterStepHook func(ctx context.Context, st *Step, status StepResultStatus, err error) (context.Context, error)

AfterStepHook defines a hook after step.

type Attachment added in v0.15.0

type Attachment struct {
	Body      []byte
	FileName  string
	MediaType string
}

func Attachments added in v0.15.0

func Attachments(ctx context.Context) []Attachment

type BaseFmt added in v0.12.0

type BaseFmt = internal_fmt.Base

BaseFmt exports Base formatter.

func NewBaseFmt added in v0.12.0

func NewBaseFmt(suite string, out io.Writer) *BaseFmt

NewBaseFmt creates a new base formatter.

type BeforeScenarioHook added in v0.12.0

type BeforeScenarioHook func(ctx context.Context, sc *Scenario) (context.Context, error)

BeforeScenarioHook defines a hook before scenario.

type BeforeStepHook added in v0.12.0

type BeforeStepHook func(ctx context.Context, st *Step) (context.Context, error)

BeforeStepHook defines a hook before step.

type CukeFmt added in v0.12.0

type CukeFmt = internal_fmt.Cuke

CukeFmt exports Cucumber JSON formatter.

func NewCukeFmt added in v0.12.0

func NewCukeFmt(suite string, out io.Writer) *CukeFmt

NewCukeFmt creates a new Cucumber JSON formatter.

type DocString added in v0.10.0

type DocString = messages.PickleDocString

DocString represents the DocString argument made to a step definition

type EventsFmt added in v0.12.0

type EventsFmt = internal_fmt.Events

EventsFmt exports Events formatter.

func NewEventsFmt added in v0.12.0

func NewEventsFmt(suite string, out io.Writer) *EventsFmt

NewEventsFmt creates a new event streaming formatter.

type Feature added in v0.12.6

type Feature = flags.Feature

type Formatter

type Formatter = formatters.Formatter

Formatter is an interface for feature runner output summary presentation.

New formatters may be created to represent suite results in different ways. These new formatters needs to be registered with a godog.Format function call

type FormatterFunc

type FormatterFunc = formatters.FormatterFunc

FormatterFunc builds a formatter with given suite name and io.Writer to record output

func FindFmt added in v0.7.9

func FindFmt(name string) FormatterFunc

FindFmt searches available formatters registered and returns FormaterFunc matched by given format name or nil otherwise

type GherkinDocument added in v0.12.0

type GherkinDocument = messages.GherkinDocument

GherkinDocument represents gherkin document.

type JUnitFmt added in v0.12.0

type JUnitFmt = internal_fmt.JUnit

JUnitFmt exports JUnit formatter.

func NewJUnitFmt added in v0.12.0

func NewJUnitFmt(suite string, out io.Writer) *JUnitFmt

NewJUnitFmt creates a new JUnit formatter.

type Options

type Options = flags.Options

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 PrettyFmt added in v0.12.0

type PrettyFmt = internal_fmt.Pretty

PrettyFmt exports Pretty formatter.

func NewPrettyFmt added in v0.12.0

func NewPrettyFmt(suite string, out io.Writer) *PrettyFmt

NewPrettyFmt creates a new pretty formatter.

type ProgressFmt added in v0.12.0

type ProgressFmt = internal_fmt.Progress

ProgressFmt exports Progress formatter.

func NewProgressFmt added in v0.12.0

func NewProgressFmt(suite string, out io.Writer) *ProgressFmt

NewProgressFmt creates a new progress formatter.

type Scenario added in v0.10.0

type Scenario = messages.Pickle

Scenario represents the executed scenario

type ScenarioContext added in v0.10.0

type ScenarioContext struct {
	// contains filtered or unexported fields
}

ScenarioContext allows various contexts to register steps and event handlers.

When running a scenario, the instance of ScenarioContext is passed to all functions (contexts), which have it as a first and only argument.

Note that all event hooks does not catch panic errors in order to have a trace information. Only step executions are catching panic error since it may be a context specific error.

func (ScenarioContext) After added in v0.12.0

func (ctx ScenarioContext) After(h AfterScenarioHook)

After registers a function or method to be run after every scenario.

func (ScenarioContext) AfterScenario deprecated added in v0.10.0

func (ctx ScenarioContext) AfterScenario(fn func(sc *Scenario, err error))

AfterScenario registers a function or method to be run after every scenario.

Deprecated: use After.

func (ScenarioContext) AfterStep deprecated added in v0.10.0

func (ctx ScenarioContext) AfterStep(fn func(st *Step, err error))

AfterStep registers a function or method to be run after every step.

It may be convenient to return a different kind of error in order to print more state details which may help in case of step failure

In some cases, for example when running a headless browser, to take a screenshot after failure.

Deprecated: use ScenarioContext.StepContext() and StepContext.After.

func (ScenarioContext) Before added in v0.12.0

func (ctx ScenarioContext) Before(h BeforeScenarioHook)

Before registers a function or method to be run before every scenario.

It is a good practice to restore the default state before every scenario, so it would be isolated from any kind of state.

func (ScenarioContext) BeforeScenario deprecated added in v0.10.0

func (ctx ScenarioContext) BeforeScenario(fn func(sc *Scenario))

BeforeScenario registers a function or method to be run before every scenario.

It is a good practice to restore the default state before every scenario, so it would be isolated from any kind of state.

Deprecated: use Before.

func (ScenarioContext) BeforeStep deprecated added in v0.10.0

func (ctx ScenarioContext) BeforeStep(fn func(st *Step))

BeforeStep registers a function or method to be run before every step.

Deprecated: use ScenarioContext.StepContext() and StepContext.Before.

func (ScenarioContext) Given added in v0.13.0

func (ctx ScenarioContext) Given(expr, stepFunc interface{})

Given functions identically to Step, but the *StepDefinition will only be matched if the step starts with "Given". "And" and "But" keywords copy the keyword of the last step for the purpose of matching.

func (ScenarioContext) Step added in v0.10.0

func (ctx ScenarioContext) Step(expr, stepFunc interface{})

Step allows to register a *StepDefinition in the Godog feature suite, the definition will be applied to all steps matching the given Regexp expr.

It will panic if expr is not a valid regular expression or stepFunc is not a valid step handler.

The expression can be of type: *regexp.Regexp, string or []byte

The stepFunc may accept one or several arguments of type: - int, int8, int16, int32, int64 - float32, float64 - string - []byte - *godog.DocString - *godog.Table

The stepFunc need to return either an error or []string for multistep

Note that if there are two definitions which may match the same step, then only the first matched handler will be applied.

If none of the *StepDefinition is matched, then ErrUndefined error will be returned when running steps.

func (ScenarioContext) StepContext added in v0.12.0

func (ctx ScenarioContext) StepContext() StepContext

StepContext exposes StepContext of a scenario.

func (ScenarioContext) Then added in v0.13.0

func (ctx ScenarioContext) Then(expr, stepFunc interface{})

Then functions identically to Step, but the *StepDefinition will only be matched if the step starts with "Then". "And" and "But" keywords copy the keyword of the last step for the purpose of matching.

func (ScenarioContext) When added in v0.13.0

func (ctx ScenarioContext) When(expr, stepFunc interface{})

When functions identically to Step, but the *StepDefinition will only be matched if the step starts with "When". "And" and "But" keywords copy the keyword of the last step for the purpose of matching.

type Step added in v0.10.0

type Step = messages.PickleStep

Step represents the executed step

type StepContext added in v0.12.0

type StepContext struct {
	// contains filtered or unexported fields
}

StepContext allows registering step hooks.

func (StepContext) After added in v0.12.0

func (ctx StepContext) After(h AfterStepHook)

After registers a function or method to be run after every step.

It may be convenient to return a different kind of error in order to print more state details which may help in case of step failure

In some cases, for example when running a headless browser, to take a screenshot after failure.

func (StepContext) Before added in v0.12.0

func (ctx StepContext) Before(h BeforeStepHook)

Before registers a function or method to be run before every step.

type StepDefinition added in v0.9.0

type StepDefinition = formatters.StepDefinition

StepDefinition is a registered step definition contains a StepHandler and regexp which is used to match a step. Args which were matched by last executed step

This structure is passed to the formatter when step is matched and is either failed or successful

type StepResultStatus added in v0.12.0

type StepResultStatus = models.StepResultStatus

StepResultStatus describes step result.

type Steps added in v0.7.1

type Steps []string

Steps allows to nest steps instead of returning an error in step func it is possible to return combined steps:

func multistep(name string) godog.Steps {
  return godog.Steps{
    fmt.Sprintf(`an user named "%s"`, name),
    fmt.Sprintf(`user "%s" is authenticated`, name),
  }
}

These steps will be matched and executed in sequential order. The first one which fails will result in main step failure.

type Table added in v0.10.0

type Table = messages.PickleTable

Table represents the Table argument made to a step definition

type TestSuite added in v0.10.0

type TestSuite struct {
	Name                 string
	TestSuiteInitializer func(*TestSuiteContext)
	ScenarioInitializer  func(*ScenarioContext)
	Options              *Options
}

TestSuite allows for configuration of the Test Suite Execution

func (TestSuite) RetrieveFeatures added in v0.12.0

func (ts TestSuite) RetrieveFeatures() ([]*models.Feature, error)

RetrieveFeatures will parse and return the features based on test suite option Any modification on the parsed features will not have any impact on the next Run of the Test Suite

func (TestSuite) Run added in v0.10.0

func (ts TestSuite) Run() int

Run will execute the test suite.

If options are not set, it will reads 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

If there are flag related errors they will be directed to os.Stderr

Example (Subtests)
package main

import (
	"testing"

	"github.com/cucumber/godog"
)

func main() {
	var t *testing.T // Comes from your test function, e.g. func TestFeatures(t *testing.T).

	suite := godog.TestSuite{
		ScenarioInitializer: func(s *godog.ScenarioContext) {
			// Add step definitions here.
		},
		Options: &godog.Options{
			Format:   "pretty",
			Paths:    []string{"features"},
			TestingT: t, // Testing instance that will run subtests.
		},
	}

	if suite.Run() != 0 {
		t.Fatal("non-zero status returned, failed to run feature tests")
	}
}
Output:

type TestSuiteContext added in v0.10.0

type TestSuiteContext struct {
	// contains filtered or unexported fields
}

TestSuiteContext allows various contexts to register event handlers.

When running a test suite, the instance of TestSuiteContext is passed to all functions (contexts), which have it as a first and only argument.

Note that all event hooks does not catch panic errors in order to have a trace information

func (*TestSuiteContext) AfterSuite added in v0.10.0

func (ctx *TestSuiteContext) AfterSuite(fn func())

AfterSuite registers a function or method to be run once after suite runner

func (*TestSuiteContext) BeforeSuite added in v0.10.0

func (ctx *TestSuiteContext) BeforeSuite(fn func())

BeforeSuite registers a function or method to be run once before suite runner.

Use it to prepare the test suite for a spin. Connect and prepare database for instance...

func (*TestSuiteContext) ScenarioContext added in v0.12.4

func (ctx *TestSuiteContext) ScenarioContext() *ScenarioContext

ScenarioContext allows registering scenario hooks.

type TestingT added in v0.14.1

type TestingT interface {
	// Name returns the name of the current pickle under test
	Name() string
	// Log will log to the current testing.T log if set, otherwise it will log to stdout
	Log(args ...interface{})
	// Logf will log a formatted string to the current testing.T log if set, otherwise it will log
	// to stdout
	Logf(format string, args ...interface{})
	// Error fails the current test and logs the provided arguments. Equivalent to calling Log then
	// Fail.
	Error(args ...interface{})
	// Errorf fails the current test and logs the formatted message. Equivalent to calling Logf then
	// Fail.
	Errorf(format string, args ...interface{})
	// Fail marks the current test as failed, but does not halt execution of the step.
	Fail()
	// FailNow marks the current test as failed and halts execution of the step.
	FailNow()
	// Fatal logs the provided arguments, marks the test as failed and halts execution of the step.
	Fatal(args ...interface{})
	// Fatal logs the formatted message, marks the test as failed and halts execution of the step.
	Fatalf(format string, args ...interface{})
	// Skip logs the provided arguments and marks the test as skipped but does not halt execution
	// of the step.
	Skip(args ...interface{})
	// Skipf logs the formatted message and marks the test as skipped but does not halt execution
	// of the step.
	Skipf(format string, args ...interface{})
	// SkipNow marks the current test as skipped and halts execution of the step.
	SkipNow()
	// Skipped returns true if the test has been marked as skipped.
	Skipped() bool
}

TestingT is a subset of the public methods implemented by go's testing.T. It allows assertion libraries to be used with godog, provided they depend only on this subset of methods.

func T added in v0.14.1

func T(ctx context.Context) TestingT

T returns a TestingT compatible interface from the current test context. It will return nil if called outside the context of a test. This can be used with (for example) testify's assert and require packages.

Directories

Path Synopsis
_examples module
cmd
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL