[rspec-users] Working outside-in with Cucumber and RSpec
dchelimsky at gmail.com
Sat Oct 25 09:33:14 EDT 2008
On Sat, Oct 25, 2008 at 5:12 AM, Matt Wynne <matt at mattwynne.net> wrote:
> There are screencasts on peepcode and also Pat Maddox has done one, but I
> think they may be a bit out of date, and more focussed on just the mechanics
> of getting up and running with the old story runner rather than the workflow
> once you get going.
> Ben Mabey's blog has some useful experiences to draw on.
> In answer to your question though, if this isn't too vague, I think this
> really sums it up:
> Start with a plain-text feature, then implement the steps behind it one by
> one. As you implement each step you'll find you need the system to do
> something. Maybe your step says "Given there is a User". Do you have a User
> class yet? Then you'd better make one. Each time you change the system
> itself (as opposed to the steps), drive out that change by writing rspec
> examples that fail because you haven't written the code yet. This is
> crucial: resist the urge to touch the code until you have a failing spec.
At the risk of creating controversy, confusion, etc, I've been playing
with the boundaries of this notion of "resisting the urge to touch the
code until you have a failing spec."
This really needs a blog post, so I'll try and drum one up, but the
short version is this:
In the past I've been very disciplined about following this rule, as
it is something that I learned back in my FitNesse/JUnit days. The
thing is, those two tools are completely decoupled. The FitNesse tests
(which map to cucumber in our ruby/bdd land) could be changed at any
time by any number of non-developer folks. They were also stored
outside of the SCM repo that the code was in.
So there was a risk to manage, which was that if somebody deleted or
changed a FitNesse test, there could be a coverage problem at the code
level, therefore high coverage from JUnit was essential.
These days I work on scenarios w/ customers, but they are ultimately
checked in directly with the rest of the code and run before a push
(I'm doing a lot of solo dev right now, so I'm not using CI since I'm
essentially integrating with every change I make :) ). Since it's all
part of the same code base, I don't feel the need to create a code
example for User just to bring a User into existence.
Using webrat within cucumber scenarios for a rails app largely
eliminates the need for view specs as well. The combination of these
tools usually provides excellent feedback and, in my view, sufficient
fault isolation, when something falls apart in a view.
Of course, as soon as an object has to do something interesting (other
than mere existence), I'll usually drop down to rspec. I don't have a
"rule" for when to do this. I'm just going by feel, and so far have
not been bitten by this approach.
And once we have a disconnected in-browser editor for scenarios, I'm
sure I'll go back to being more disciplined about starting from a code
example in rspec.
But in the mean time, cucumber steps ARE code examples, and as long as
they live closely bound to the code (in the same SCM repo), I think
it's OK to consider them your starting point (example first) and not
require an rspec code example just to bring an object into existence.
And *that* was the short version :)
> You can then use the usual TDD cycle to change the classes that make up the
> system, then finally surface back up to the feature, run it, and see what
> you need to do next.
> The point of the cucumber features is not to exhaustively cover every single
> path in your code - that's the job of the specs (examples). The features
> give you a safety net to tell you that it all fits together.
> Does that make any more sense or have I just regurgetated Aslak's words from
> the Cucumber readme?!
> On 25 Oct 2008, at 10:34, Tom Stuart wrote:
>> Going to dive into Cucumber soon, and just reading through all the docs
>> Can anyone point to an example of writing Cucumber features first and then
>> "when you get down to nitty gritty details, drop down one abstraction level
>> and use RSpec to write some specs for your classes" (as per Cucumber wiki)?
>> I'm trying to get a good feeling for the process of starting with a feature,
>> dropping straight down to implementing code, and then somehow coming halfway
>> back up and filling in the specs. Which levels of granularity are we talking
>> about here? If you write a feature and then write enough code to make the
>> feature pass, how do the specs still have traction to drive the design?
>> rspec-users mailing list
>> rspec-users at rubyforge.org
> rspec-users mailing list
> rspec-users at rubyforge.org
More information about the rspec-users