[rspec-users] Cucumber - Adding a step definition

Matt Wynne matt at mattwynne.net
Sat Mar 14 21:18:46 EDT 2009

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

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)

With /a secondary risk/ do
   @it.secondary_risk = true

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

More information about the rspec-users mailing list