On 9 Sep 2008, at 19:52, Jim Morris wrote:
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.
I think the scenarios are each wrapped in a transaction, so (as long
as you're using the right type of database / tables) the slate should
be wiped clean between each one.
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.
I've been thinking about this a bit, after reading Aslak's advice
which went contrary to my instincts. It seems like you could probably
do something like this instead:
Scenario: testing a pet
Given I have a pet
When I stroke the pet
Then the pet's health goes up
Because your Given step creates just one Pet instance, you can safely
refer to it as "the pet" in the other steps, and simply call Pet.find
(:first) in the step matcher.
See?
In a more complicated scenario:
Scenario: testing a pet
Given I have two pets named "my dog" and "my cat"
When I stroke "my dog"
Then "my cat" should be pissed off
Now your step matcher needs to refer to a particular pet, but can't
it just use the name as a key, since that will be unique within the
set of two Pet records you created in your Given step?
When /I stroke "(.*)"/ |pet_name| do
Pet.find_by_name(pet_name).stroke
end
Does that make sense to you?
cheers,
Matt
----
http://blog.mattwynne.net
http://songkick.com
In case you wondered: The opinions expressed in this email are my own
and do not necessarily reflect the views of any former, current or
future employers of mine.
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users