[rspec-users] Best practices for sharing state between story steps?

Jim Morris ml at e4net.com
Tue Sep 9 14:52:10 EDT 2008


aslak hellesoy wrote:

> The debate seems to be whether step definitions should be stateful or not.
> In practice this is achieved by setting one or more @variables in a
> step and reusing them in a different step - all within a scenario.
> 

I think that is the debate, but I'd like to point out that there is always state between steps, it 
is just a matter of where it is being kept. In your example for instance most of the state is being 
kept in the database between steps (ie between Given an "active" site_user names "aslak" and he 
following steps.

(As a side question how do you clean up the database between tests, so the "state" from the previous 
Scenario doesn't affect the next Scenario?) In some cases I use a randomly generated record each time.

> 
> Here is an example of a stateless scenario: (As a convention I'm
> "quoting" variables)
> 

That is quite interesting, however as I pointed out above there is state between steps, in the 
database and in the response.

I actually do something very similar, with named resources in each step, however I find I still need 
to use variables between steps, here is an example... (Not rails)

Scenario: testing a pet
   Given I have a pet named "my dog"
   When I stroke "my dog"
   Then "my dog"'s health goes up

In the Given I create a pet named "my dog" in the database either directly or through the REST-ful 
API to my Web app, however in both cases I need the returned id of the created pet to make any 
further calls on it.

In the When clause I need to make an API call that pets "my dog", the API is POST stroke/345
So what I do is in the Given I assign the returned id of the new record to $petid, then in the When 
clause I do something like, $http_req.post("stroke", id => $petid).

Now I needed to carry that variable $petid around otherwise how would I be able to make the call in 
When.

Similarly when I want to check my pets health in the Then clause I still need that $petid, whether I 
check the value directly in the database or make an API call that returns my pets health.

I don't see anyway around keeping state in these cases.

Now I do clear that state ($petid= nil) in the before_scenario hook, so another scenario which may 
be written badly and not assign the $petid, won't succeeed due to a previously successful scenario.

I'd definitely be interested in better ways to do this though, as I hate passing global variables 
around (as I said in an earlier post I can't use @variable because the before_scenario does not seem 
to have access to the same scope as the scenario that is about to run). Although I think someone 
said each scenario has its own variables? I didn't notice that behavior.


-- 
Jim Morris, http://blog.wolfman.com


More information about the rspec-users mailing list