What is your workflow? Or how to use the story runner the right way

I really would like to know how people are using the Story and Example
runner to write their software.It would be great to get some direction
on
it, because I think I’m missing some points.

Taking the outside-in approach in thought:

At first we write a high-level customer-facing story, this story fails.
Then we start using mocks at object level to use them as a design tool,
and so we implement the different layers of the system.
After implementing the inner layer, the story should pass.
When that happens we could remove the mocks and replace it with calls to
the
real code, making the suite less brittle (except for calls to external
services/databases/file systems).

So if the story passes all acceptance tests, why is there a need for
examples at a lower level?

On 4 Mar 2008, at 13:13, Matthijs L. wrote:

calls to external services/databases/file systems).
Don’t use mocks at the story level. IMHO stories should always be
using the full stack. This includes your database, but you might be
permitted to exclude external services such as credit card billing
systems. However, if you can set up a sandbox to test against (such as
the Paypal sandbox), all to the good.

We proceed based on two principles:

A failure in a story means you change specs not code.
A failure in a spec means you change the code.

This is how we do it (assuming a rails application):

  1. Write customer story, all steps are pending:

Scenario: Viewing the front page
When I view the front page
Then I see the text ‘welcome to the app’

  1. Write the first step in the story:

When “I view the front page” do
get “/”
end

This then fails, as I don’t have a front page yet!

  1. Pay attention to the error given by the story, and fix that by
    writing a spec
    .

In this case it’ll be complaining that the controller doesn’t exist.
At this point I drop down to the specs as a failing story means we
need a spec:

describe MainController do
end

  1. Make your specs pass.

‘rake spec’ then fails, as MainController doesn’t exist. In this case,
I add a controller and a route (by hand, none of that scaffold
business):

class MainController < ApplicationController
end

  1. Run the story again if you need to, and use that as a guide to
    write more specs. Repeat steps 4 and 5.

To continue the example - in this case it’ll probably complain about
no index action:

describe MainController do
it “should handle an index action” do
get :index
end
end

and then, to fix the spec:

class MainController < ApplicationController
def index
end
end

Then it’ll most likely complain about not having an index.html.erb.
Because controller specs don’t render the page, you’ll need an an
index.html.erb_spec.rb to test the view properly. And so on.

Sound like a lot of work, but given practice you can zip through these
steps very quickly. You also get a free ‘focusing tool’ (lose sight of
where you are? just run the story test and write more specs).

Hope this is helpful. Maybe I should write up an extended example as a
blog post, including mocking etc, as it seems to come up a lot.

Thanks
Chris

PS: Excuse the spelling/coding mistakes in the (untested) code :slight_smile:
Corrections and comments as to the methodology here most welcome.


Chris Parsons
Managing Director
Eden Development (UK) Ltd

[email protected]
www.edendevelopment.co.uk

0845 0097 094
po box 425, winchester, so23 0wy, uk
Map: http://pininthemap.com/edendevelopment

Tried Pin in the Map? Mark a map location, add text, send to friends.
http://pininthemap.com

This electronic message and all contents contain information from the
sender which may be privileged, confidential or otherwise protected
from disclosure. The information is intended to be for the
addressee(s) only. If you are not an addressee, any copying,
disclosure, distribution or use of the contents of this message is
prohibited. If you have received this electronic message in error,
please notify the sender by reply e-mail and destroy the original
message and all copies. The sender does not accept liability for any
errors or omissions.

On Tue, Mar 4, 2008 at 7:13 AM, Matthijs L.
[email protected] wrote:

After implementing the inner layer, the story should pass.
When that happens we could remove the mocks and replace it with calls to the
real code,

I do this sometimes - removing the mocks - as long as the objects are
trivial to set up and they don’t have dependencies that I don’t want
to expose. There’s no one way to do this, and I’ll sometimes remove
mocks and reintroduce them over the life of a project.

making the suite less brittle

What brittle means is a bit subjective here. Just a lengthy
conversation about this in irc last night. The guy with whom I was
chatting prefers to not use mocks because he’d rather see a change
cause a bunch of lower level examples to fail than stories. From what
I can tell, he doesn’t like to use mocks even temporarily, in process.

His approach has the benefit that you learn about side effects of your
changes faster, and the cost that it means you sometimes have more
“red bar” to wade through while you get things right.

My approach has the benefit that you can address side effects of your
changes with a green bar helping you know that the smaller bits
(objects and methods) are functioning, and the cost that you sometimes
don’t learn about side effects until you run your stories (or
integration suite).

Neither solution is perfect. You just have to pick your poison.

(except for calls to external
services/databases/file systems).

This is a funny thing about ruby, specifically rails.

One of the hallmarks of OO is a high level of decoupling - especially
decoupling your code from 3rd party code through adapters. There are a
couple of reasons for this.

One is that having an adapter lets you write exactly the code that you
want to write throughout most of your system, rather than being
subject to the naming conventions of the 3rd party library that might
clash with those in your system or even with your domain.

The other is that if you decide to switch to a different library,
you’re pretty well hosed unless you have adapters. If you look at the
competitors to ActiveRecord, like Og and Datamapper, they are all VERY
similar syntactically. Why? Two reasons I think. One is that AR got a
lot of things right from a domain perspective. The other is that calls
to AR internals have leaked out to a lot of controllers and even
views:

Person.find(:all, :conditions => [‘active = ?’, true])

In spite of guidelines all over the web that say that this should be
wrapped in a #find_active method in the model, these sorts of things
pop up all over the place anyhow.

So if the story passes all acceptance tests, why is there a need for
examples at a lower level?

So that you can get things working one step at a time, and then change
things as needed one step at a time, with green bars keeping you sane,
stress free, and even happy all the way through.

HTH,
David

On Tue, Mar 4, 2008 at 6:13 AM, David C. [email protected]
wrote:

What brittle means is a bit subjective here. Just a lengthy
conversation about this in irc last night. The guy with whom I was
chatting prefers to not use mocks because he’d rather see a change
cause a bunch of lower level examples to fail than stories.

Do you happen to have a log of that convo?

Pat

On Tue, Mar 4, 2008 at 8:13 AM, David C. [email protected]
wrote:

Then we start using mocks at object level to use them as a design tool,

“red bar” to wade through while you get things right.

(except for calls to external
subject to the naming conventions of the 3rd party library that might
Person.find(:all, :conditions => [‘active = ?’, true])

In spite of guidelines all over the web that say that this should be
wrapped in a #find_active method in the model, these sorts of things
pop up all over the place anyhow.

Finishing up that thought - find_active is an adapter - just at the
method level instead of the object level.

On Tue, Mar 4, 2008 at 10:43 AM, Pat M. [email protected] wrote:

On Tue, Mar 4, 2008 at 6:13 AM, David C. [email protected] wrote:

What brittle means is a bit subjective here. Just a lengthy
conversation about this in irc last night. The guy with whom I was
chatting prefers to not use mocks because he’d rather see a change
cause a bunch of lower level examples to fail than stories.

Do you happen to have a log of that convo?

It was in caboose - are those public?

On Tue, Mar 4, 2008 at 8:46 AM, David C. [email protected]
wrote:

It was in caboose - are those public?

Nope

On Tue, Mar 4, 2008 at 9:11 AM, Pat M. [email protected] wrote:

Do you happen to have a log of that convo?

It was in caboose - are those public?

Nope

Nevermind, turns out that I work with this nutcase

Thanks Chris. This is a really nice description of how I think of BDD. I
call it “we should fix that” after Liz Keogh’s blog post:
http://sirenian.livejournal.com/42871.html

(Check the comments for the myriad ways you can misinterpret this!)

Cheers,
Dan

On Mar 4, 2008, at 7:43 AM, Chris Parsons wrote:

Chris
Sorry to resurrect an old thread…

I’ve just spent the last 10 hours working on understanding user
stories and their role in designing code.

Here’s what I’ve done:

  • watched the “RSpec User Stories” peepcode
  • scoured this newsgroup for tips & suggestions
  • used Chris’ methodology to BDD a new app

So far things are going well though the process is S L O W. I’ve tried
to cobble together tips from other threads regarding directory
structure for the stories, steps & specs amongst other things, but it
just feels really scattered to me.

I would love to see Chris put together a more detailed example of his
workflow. It’s likely I am making some boneheaded mistakes that I just
can’t pick out yet.

When I’m further with my example project, I’ll try to post it up
somewhere (or turn it into doc for the rspec site) so others can learn
from my mistakes.

cr

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs