[rspec-users] Cucumber - Adding a step definition

Josh Chisholm joshuachisholm at gmail.com
Sun Mar 15 03:55:43 EDT 2009


I like that heuristic Matt.

Actually coupling via the database is quite different to instance
variables. The database state would exist if you followed through the
scenario without cucumber e.g. manually.

It occurred to me you could avoid the table like this too:

Given a policy with a PCF practice state, secondary risk and something else

Given /^a policy with (.+)$/ do | attributes |
  # create policy
  attributes.split(/(?:(?:,|\sand)\s)/).each do | attribute |
    # apply attributes "a PCF practice state", "secondary risk",
"something else"
  end
end

Josh

On Sun, Mar 15, 2009 at 1:18 AM, Matt Wynne <matt at mattwynne.net> wrote:
>
> On 15 Mar 2009, at 00:30, Josh Chisholm wrote:
>
>>> That sounds like a great way to avoid the instance variable.
>>
>> Why is a named record preferable to an instance variable? It seems
>> like the coupling between steps is the same, but the coupled state is
>> stored differently. Maybe that's the point - stored differently.
>
> I guess my view is that having the state out front in the scenario is
> preferable whenever possible (without cluttering up the feature with noise)
> because it's clear, and there's less risk of a gap opening up between what
> the step appears to do given its name, and what it actually does when it
> runs. I take this gap seriously because I put a great deal of trust our
> features.
>
>> I've been tempted to start scenario lines with "With" as well, to get
>> away from the combinatorial explosion of setup steps for complex
>> entities (think decorator pattern). I've used tables too, but mine
>> looked more like this:
>>
>> Given a policy with:
>>  | PCF practice state | secondary risk |
>>  | yes                         | yes                   |
>>
>> Is that nasty? It means we can use one step to set all possible
>> boolean attributes of a policy, but it doesn't read so well.
>
> I don't think that's nasty, it seems entirely appropriate for that type of
> problem. It sounds like the type of acceptance tests I hear people like
> Keith Braithwaite talking about putting together for traders using Excel and
> Fit, and they seem to work really well.
>
> Thinking about this some more though, maybe there's an argument for breaking
> the feature up into multiple features, and using Background to set up the
> common state of the objects, then have a few scenarios that build on this
> with different steps to tweak the objects. Just another idea - it's really
> hard to judge without seeing more of the specific features.
>
>> "With ..." would mean steps that were coupled to the "last mentioned
>> thing". That seems like a different kind of coupling - there is only
>> one piece of state involved (the last thing) rather than a map of
>> named things. But it's less explicit and implies that the "last thing"
>> needs to be updated by each step that mentions things.
>
> I know what you mean, and it would certainly make for nice readable
> scenarios. My worry is how maintainable the steps would be in the long run.
> I'm used to seeing steps like this:
>
> Given /the Policy has a secondary risk/ do
>  Policy.count.should == 1
>  policy = Policy.first
>  policy.secondary_risk = true
>  policy.save
> end
>
> Which are pretty explicit and leave no room for accidental abuse. What the
> OP suggested would give you something more like this:
>
> Given /a Policy/ do
>  @it = Factory(:policy)
> end
>
> With /a secondary risk/ do
>  @it.secondary_risk = true
>  @it.save
> end
>
> I dunno actually. Now I type it out it doesn't seem so bad :)
>
>
>> Matt, going back to Mark's example, it sounds like you lean towards
>> the latter (i.e. repeat 'Reach from the Stars for 'Halo 3' throughout
>> the scenario). Is that correct?
>
> I guess my heuristic is something like this:
>
> 1. If I can simply refer to "the Widget" then I do, wherever possible.
>
> 2. If some attribute of the Widget is important in the scenario, I'll
> explicitly set that attribute, and mention it again later in the assertions.
> e.g.
>  Given a Widget named "Foo"
>  When I delete the Widget
>  Then I should see the text "bye bye Foo"
>
> 3. If I have to refer to multiple objects of the same class in one scenario,
> then I use names to differentiate between them. e.g.
>  Given some Widgets named "Foo, Bar"
>  When I delete the Widget "Foo"
>  Then I should see 1 Widget
>  And I should see the text "Bar"
>
>
> Matt Wynne
> http://blog.mattwynne.net
> http://www.songkick.com
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list