A lifesaver expander for cucumber/godog because, sometimes, you have to use variables in your steps.
Go >= 1.16
go get github.com/godogx/expandvarsInitiate a new StepExpander with expandvars.NewStepExpander() then add it to ScenarioInitializer by
calling StepExpander.RegisterContext(*testing.T, *godog.ScenarioContext)
package main
import (
"fmt"
"math/rand"
"strings"
"testing"
"github.com/cucumber/godog"
"github.com/godogx/expandvars"
"github.com/stretchr/testify/assert"
)
func TestIntegration(t *testing.T) {
expander := expandvars.NewStepExpander(
strings.NewReplacer("$TO", "Berlin"),
expandvars.Pairs{
"HUSBAND": "John",
},
func() expandvars.Pairs {
return expandvars.Pairs{
"RAND": fmt.Sprintf("%d", rand.Int63()),
}
},
expandvars.BeforeScenario(func() expandvars.Pairs {
return expandvars.Pairs{
"SCENARIO_RAND": fmt.Sprintf("%d", rand.Int63()),
}
}),
func(s string) string {
return strings.ReplaceAll(s, "$FROM", "Paris")
},
expandvars.Expander(func(s string) string {
return strings.ReplaceAll(s, "$TRANSPORT", "by bus")
}),
// OS env vars.
expandvars.EnvExpander,
)
suite := godog.TestSuite{
Name: "Integration",
ScenarioInitializer: func(ctx *godog.ScenarioContext) {
expander.RegisterContext(ctx)
},
Options: &godog.Options{
Strict: true,
Randomize: rand.Int63(),
},
}
// Run the suite.
}In your tests, just use $VARIABLE_NAME in the step or the argument, like this:
Scenario: var is replaced
Given var NAME is replaced in step text: $NAME
Then step text is:
"""
map var NAME is replaced in step text: John
"""
Given var NAME is replaced in step argument (string)
"""
NAME=$NAME
"""
Then step argument is a string:
"""
NAME=John
"""
Given env var NAME is replaced in step argument (table)
| col 1 | col 2 | col 3 |
| value 1 | $NAME | value 3 |
Then step argument is a table:
| col 1 | col 2 | col 3 |
| value 1 | John | value 3 | Scenario: .github files
Then there should be only these files in "$TEST_DIR/.github":
"""
- workflows:
- golangci-lint.yaml
- test.yaml
"""The expanders could be any of these:
- A
Replacerinterface
type Replacer interface {
Replace(string) string
}-
A
Replacerfunc(string) stringfunction.
For example, you could useos.ExpandEnvor its aliasexpandvars.EnvExpander -
A map or vars (without the
$)map[string]string
var _ = expandvars.NewStepExpander(expandvars.Pairs{
"HUSBAND": "John",
"WIFE": "Jane",
})- A provider that provides a map of vars (without the
$)map[string]string. The provider will be called every step.
var _ = expandvars.NewStepExpander(func() expandvars.Pairs {
return map[string]string{
"RAND": fmt.Sprintf("%d", rand.Int63()),
}
})- A
BeforeScenarioprovides a map of vars (without the$)map[string]string. The provider will be called only once before every scenario.
Note: If you need expandvars.EnvExpander or os.ExpandEnv, put it in the end of the chain. Because it replaces not-found vars with empty strings, other
expanders won't have a chance to do their jobs if you put it in the beginning.