[rspec-users] Best practices for sharing state between story steps?
tastapod at gmail.com
Tue Sep 9 08:21:59 EDT 2008
I guess I'm not a purist then - that looks fine to me, and it's probably
something I would consider doing too.
The thing to bear in mind is that there is magic going on when you run
steps. Each step in a scenario is run in the context of the same object
instance (which you don't get to see explicitly) by pixies, which means any
@variables you set in one step should be visible to any other steps in the
same scenario. I don't think of this as global state - it's simply a
sensible way to share state across steps. You can think of the object the
steps run in as a "world" (it might even still be called that - it was at
one point) where you can set and verify state.
There are bound to be pathological cases though, such as the before_scenario
and after_scenario listeners. Perhaps there's a bug there, in that they
should be running in the same object instance as the scenario steps
themselves. Perhaps not. In the latter case I would definitely go with
$globals to communicate state into your scenario, as long as you promise
never to use them in your application code. Never, you hear me?
2008/9/8 Jim Morris <ml at e4net.com>
> Sam Stokes wrote:
>> Jonathan Linowes wrote:
>>> I make some limited use of global (instance) variables that
>>> correspond to english language pronouns. I have things like
>>> @current_user (corresponds to "I"), @current_project (corresponds to
>>> "the project"), etc. I am careful to be consistent. There's only a
>>> handful of these, but I find it extremely convenient. Note, these
>>> also tend correspond to 'states' in my app, which might be in the
>>> session or part of a nested URL.
>> So could I summarise this approach as, "use @variables, with good names
>> and consistent principles for use"?
> I'm of the opinion "do what works". I know there are purists that say don't
> do this and don't do that, but when you come down to it you have to use
> variables between steps, look at the rails examples and it sets a response
> variable between steps.
> What I do is horrible :) but "it works", I set GLOBAL variables (yup
> $current_state), because I found that sometimes @variable didn't get setup
> properly in some cases.
> Then I use the listeners to clear those variables between scenarios, so
> every scenario I have a listener (effectively before_scenario), that clears
> all the global variables I use between steps, this avoids errors where I
> don't set up something in a step but the scenario passes because it just
> happens to have the right value in a global set by a previous test.
> This does require some maintenance, however I could use a global hash for
> my inter-step-dependencies, and just $hash.clear in the before_scenario
> Ahh I remember why I had to use $variable and not @variable, for some
> reason the before_scenario listener does not have access to the same scope
> as the scenario so I have to use $variables.
> So most of my scenarios look like this....
> before_scenario do
> $v1= nil
> $v2= nil
> Scenario "xxx" do
> Given "something..."
> When "I do something" # this will set $v1 and $v2
> Then "check it was done" # this will check $v1 and $v2
> I know purists will hate this ;) But "it works for me"
> BTW I use stories entirely for integration testing, testing the entire
> stack by using the same inputs (in my case a WEB based REST API) to the
> stack as a client would.
> I also do nasty things like delve into the database directly in a Then to
> check the database actually got setup the way I expected by a previous When,
> as well as checking the returned XML from the Rest-API call.
> As always YMMV
> Jim Morris, http://blog.wolfman.com
> rspec-users mailing list
> rspec-users at rubyforge.org
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the rspec-users