Added an example for how to use assertion pkgs like testify with godog

Этот коммит содержится в:
Fredrik Lönnblad 2020-05-02 18:52:19 +02:00
родитель 075d624710
коммит bfee72ddec
4 изменённых файлов: 165 добавлений и 2 удалений

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

@ -77,8 +77,7 @@ themselves from costly regressions.
## Example
The following example can be [found
here](/_examples/godogs).
The following example can be [found here](/_examples/godogs).
### Step 1
@ -345,6 +344,40 @@ is one of the following:
- `@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](/_examples/assert-godogs).
``` go
/* file: $GOPATH/src/assert-godogs/godogs_test.go */
func thereShouldBeRemaining(remaining int) error {
return assertExpectedAndActual(
assert.Equal, Godogs, remaining,
"Expected %d godogs to be remaining, but there is %d", remaining, Godogs,
)
}
// assertExpectedAndActual is a helper function to allow the step function to call
// assertion functions where you want to compare an expected and an actual value.
func assertExpectedAndActual(a expectedAndActualAssertion, expected, actual interface{}, msgAndArgs ...interface{}) error {
var t asserter
a(&t, expected, actual, msgAndArgs...)
return t.err
}
type expectedAndActualAssertion func(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool
// asserter is used to be able to retrieve the error reported by the called assertion
type asserter struct {
err error
}
// Errorf is used by the called assertion to report an error
func (a *asserter) Errorf(format string, args ...interface{}) {
a.err = fmt.Errorf(format, args...)
}
```
### Configure common options for godog CLI
There are no global options or configuration files. Alias your common or

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

@ -0,0 +1,15 @@
# file: $GOPATH/godogs/features/godogs.feature
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 4
Then there should be 7 remaining
Scenario: Eat 12 out of 12
Given there are 12 godogs
When I eat 11
Then there should be none remaining

7
_examples/assert-godogs/godogs.go Обычный файл
Просмотреть файл

@ -0,0 +1,7 @@
/* file: $GOPATH/src/godogs/godogs.go */
package main
// Godogs available to eat
var Godogs int
func main() { /* usual main func */ }

108
_examples/assert-godogs/godogs_test.go Обычный файл
Просмотреть файл

@ -0,0 +1,108 @@
/* file: $GOPATH/src/assert-godogs/godogs_test.go */
package main
import (
"flag"
"fmt"
"os"
"testing"
"github.com/cucumber/godog"
"github.com/cucumber/godog/colors"
messages "github.com/cucumber/messages-go/v10"
"github.com/stretchr/testify/assert"
)
var opt = godog.Options{Output: colors.Colored(os.Stdout)}
func init() {
godog.BindFlags("godog.", flag.CommandLine, &opt)
}
func TestMain(m *testing.M) {
flag.Parse()
opt.Paths = flag.Args()
status := godog.RunWithOptions("godogs", func(s *godog.Suite) {
FeatureContext(s)
}, opt)
if st := m.Run(); st > status {
status = st
}
os.Exit(status)
}
func thereAreGodogs(available int) error {
Godogs = available
return nil
}
func iEat(num int) error {
err := assertExpectedAndActual(
assert.GreaterOrEqual, Godogs, num,
"You cannot eat %d godogs, there are %d available", num, Godogs,
)
if err != nil {
return err
}
Godogs -= num
return nil
}
func thereShouldBeRemaining(remaining int) error {
return assertExpectedAndActual(
assert.Equal, Godogs, remaining,
"Expected %d godogs to be remaining, but there is %d", remaining, Godogs,
)
}
func thereShouldBeNoneRemaining() error {
return assertActual(
assert.Empty, Godogs,
"Expected none godogs to be remaining, but there is %d", Godogs,
)
}
func FeatureContext(s *godog.Suite) {
s.Step(`^there are (\d+) godogs$`, thereAreGodogs)
s.Step(`^I eat (\d+)$`, iEat)
s.Step(`^there should be (\d+) remaining$`, thereShouldBeRemaining)
s.Step(`^there should be none remaining$`, thereShouldBeNoneRemaining)
s.BeforeScenario(func(*messages.Pickle) {
Godogs = 0 // clean the state before every scenario
})
}
// assertExpectedAndActual is a helper function to allow the step function to call
// assertion functions where you want to compare an expected and an actual value.
func assertExpectedAndActual(a expectedAndActualAssertion, expected, actual interface{}, msgAndArgs ...interface{}) error {
var t asserter
a(&t, expected, actual, msgAndArgs...)
return t.err
}
type expectedAndActualAssertion func(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool
// assertActual is a helper function to allow the step function to call
// assertion functions where you want to compare an actual value to a
// predined state like nil, empty or true/false.
func assertActual(a actualAssertion, actual interface{}, msgAndArgs ...interface{}) error {
var t asserter
a(&t, actual, msgAndArgs...)
return t.err
}
type actualAssertion func(t assert.TestingT, actual interface{}, msgAndArgs ...interface{}) bool
// asserter is used to be able to retrieve the error reported by the called assertion
type asserter struct {
err error
}
// Errorf is used by the called assertion to report an error
func (a *asserter) Errorf(format string, args ...interface{}) {
a.err = fmt.Errorf(format, args...)
}