-
Notifications
You must be signed in to change notification settings - Fork 248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new contextualized API for hooks and steps #409
Conversation
Codecov Report
@@ Coverage Diff @@
## main #409 +/- ##
==========================================
- Coverage 83.72% 82.88% -0.84%
==========================================
Files 26 26
Lines 2390 2454 +64
==========================================
+ Hits 2001 2034 +33
- Misses 296 323 +27
- Partials 93 97 +4
Continue to review full report at Codecov.
|
@vearutop can you include an example of sharing data across step definitions? |
@priyankshah217 please check this example https://play.golang.org/p/lSnIIlf4Puw Feature: Passing state
Scenario: Passing state between steps
# Saving state of total number of godogs
Given I have a random number of godogs
# Reading state to eat total number of godogs
When I eat all available godogs
Then there are no godogs left package main
import (
"context"
"errors"
"io/ioutil"
"log"
"math/rand"
"os"
"github.com/cucumber/godog"
)
type godogEater struct{ cnt uint32 }
func (ge *godogEater) Add(cnt uint32) { ge.cnt += cnt }
func (ge *godogEater) Available() uint32 { return ge.cnt }
func (ge *godogEater) Eat(cnt uint32) error {
if cnt > ge.cnt {
return errors.New("can't eat more than I have")
}
ge.cnt -= cnt
return nil
}
type cntCtxKey struct{} // Key for a particular context value.
func main() {
if err := ioutil.WriteFile("/tmp/state.feature", []byte(`
Feature: Passing state
Scenario: Passing state between steps
Given I have a random number of godogs
When I eat all available godogs
Then there are no godogs left
`), 0600); err != nil {
log.Fatal(err)
}
defer os.Remove("/tmp/state.feature")
eater := godogEater{}
suite := godog.TestSuite{
ScenarioInitializer: func(s *godog.ScenarioContext) {
// Creating a random number of godog and storing it in context for future reference.
s.Step("I have a random number of godogs", func(ctx context.Context) context.Context {
cnt := rand.Uint32()
println("adding random godogs", cnt)
eater.Add(cnt)
return context.WithValue(ctx, cntCtxKey{}, cnt)
})
// Getting previously stored number of godogs from context.
s.Step("I eat all available godogs", func(ctx context.Context) error {
cnt := ctx.Value(cntCtxKey{}).(uint32)
println("eating random godogs", cnt)
return eater.Eat(cnt)
})
s.Step("there are no godogs left", func() error {
if eater.Available() != 0 {
return errors.New("there are still a few godogs")
}
return nil
})
},
Options: &godog.Options{
Format: "pretty",
Strict: true,
NoColors: true,
Paths: []string{"/tmp/state.feature"},
},
}
if suite.Run() != 0 {
log.Fatal("non-zero status returned, failed to run feature tests")
}
} |
@vearutop thanks for your help. |
hey hey this closed out two issues i was following on this repo. not using godog currently but thanks for the work :) |
@vearutop I need some help, I was trying ur example and it worked fine. But have a question related to what if step def contains some parameters and how can we pass context (refer below example)? would you please give me some examples?
|
@priyankshah217, you can add context as a first argument to any step definition, so if you have one numeric argument, you can declare step as // Creating a number of godog and storing it in context for future reference.
s.Step("I have a (\d+) number of godogs", func(ctx context.Context, cnt int) context.Context {
println("adding godogs", cnt)
eater.Add(cnt)
return context.WithValue(ctx, cntCtxKey{}, cnt)
}) Please also check examples in release notes: https://github.com/cucumber/godog/blob/main/release-notes/v0.12.0.md#step-definition-improvements. |
Description
This PR introduces new API for hooks and steps that includes context and errors.
Motivation & context
In order to grant more control to test suite user, we can upgrade the API for hooks and steps.
This PR implements new API suggested in #360 (comment).
Original API is left for backwards compatibility with deprecation comments.
Step definitions now optionally support having
ctx context.Context
as a first argument.Step definition may have one of the following returns processed with help of reflection:
context.Context
- newly addederror
(context.Context, error)
- newly addedThe context is chained though all hooks and steps allowing pass state of earlier actions to later ones.
Resolves #360.
Resolves #88.
Resolves #175 with ability to inject Scenario specific data to context and read it back from Step hook.
Resolves #397.
Resolves #370.
Resolves #378.
Type of change
Note to other contributors
No note.
Update required of cucumber.io/docs
Not sure.
Checklist: