-
-
Notifications
You must be signed in to change notification settings - Fork 17
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
Make the context accessible in before/after scenarios #50
Comments
yeah, that can be useful. Initially, "before the scenario" was used to clean up some DB tables etc so I didn't need any context here but it sounds reasonable. |
@sagikazarmark how do you want to give access to the service? Do you want to put it to the context or use some kind of "global state"? |
I kinda like the "previous" context approach, where I could just mutate the context and set a value. IMHO it's definitely better than using global state. The alternative is registering member functions of a struct, but then I have to manually maintain separate instances of my service for the different scenarios. |
hmm, I will get a second opinion about it and then we'll make a decision. The reason why I changed it was that I could provide only support for basic types and to support them I had to write a few code generators what looked a bit hacky to me (a lot of copy&pasted code). Without it was just a regular map hidden behind an interface. That's what the pkg |
Yeah, I get that, but I think the context in this case is not something that propagates through a request, but a central state store everything goes to, so IMHO a purpose-built structure is justified. Also, I would maximize for readability even at the cost of "architectural correctness", because it's an incredibly important property of tests. |
I've been thinking about it. Could you give me an example scenario where you needed the context in the Here's how I used it: I create a DB connection in So it looks similar to: Background:
I have a list of products in my shop #here I add the product and the user I work on
Scenario: adding a product to the basket
Given I'm logged in user
When I add the product "abc" to the bucket
Then the total price in the basket should be equal to 123
When I add the product "cba" to the bucket
Then the total price in the basket should be equal to 222 In before/after, I just do the more "technical" work like creating connections to db/queue etc. What's your approach? I want to understand the need better to make a better decision :) |
How do you access the created db connection in your steps? I'd like to avoid creating global instances. Also, I would probably like to instantiate a service instance at the beginning of every scenario, not just the DB. So I would instantiate a service in a before scenario, set it in the context, and call service methods in steps. |
Just to support this for our use cases:
I understand the point to hide technical, non-interesting code into the I would personally prefer not to use Same as @sagikazarmark , it would involve service(s), not just a DB connection and we hate to create global instances to make it work - currently with using godog. So accessing context in the hooks, would be crucial for us. |
can you give an example scenario? I want to understand you better |
Here is what I have in mind: func TestScenario(t *testing.T) {
suite := bdd.NewSuite()
suite.BeforeSuite(func(ctx Context) {
db := NewDB()
ctx.Set("db", db)
})
suite.BeforeScenario(func(ctx Context) {
service := NewService(ctx.Get("db"))
ctx.Set("service", service)
})
suite.AfterSuite(func(ctx Context) {
db := ctx.Get("db")
db.Cleanup()
db.Close()
})
// Here is the important bit:
// functions are not inline, they don't have access to the context of TestScenario
suite.Step(serviceCallStep)
suite.Step(verifyStep)
}
func serviceCallStep(ctx Context) {
service := ctx.Get("service")
err := service.Call()
ctx.Set("error", err)
}
func verifyStep(ctx Context) {
err := ctx.GetError("error")
if err != nil {
panic("the universe is broken")
}
} Technically, these are not business actions (setting up a service is a purely technical one. Background is for things like setting initial state) |
when the |
Yes, they are simple steps |
ok, let's go for it :) |
Is your feature request related to a problem? Please describe.
Given I have a service that I have to initialize and want to do that per scenario run (so that each scenario can run with a clean state).
I would like to initialize this service and make it available to the steps.
Describe the solution you'd like
Since currently context is the way to share state between step functions and before scenario seems to be the logical place for initialization, it should probably receive the context.
On second thought, I'm not 100% how before suite hook is actually useful without this.
Describe alternatives you've considered
One could have a
Given
statement inBackground
for initialization, but that would be ugly.Additional context
Probably the same is true for after suite hooks.
The text was updated successfully, but these errors were encountered: