[rspec-users] Role of stories vs specs

David Chelimsky dchelimsky at gmail.com
Tue Nov 13 14:51:53 EST 2007


On Nov 13, 2007 1:10 PM, Pat Maddox <pergesu at gmail.com> wrote:
> I've been thinking about the role that stories played compared to
> specs, and that "should we use should" thread brought those thoughts
> up again.
>
> First I want to discuss whether or not specs are authoritative
> regarding the desired behavior of a system.  I would say they're a
> good approximation of how the system currently runs according to the
> developer's understanding.  I say they're an approximation because if
> you use mocks everywhere (as I believe you ought to) then you're not
> performing integrations and the specs are necessarily incomplete.
>
> Why does that idea matter?  Traditionally, we've leaned heavily on a
> suite of unit tests to perform refactorings.  In fact, Fowler says the
> first thing you have to do in order to refactor is grow a set of
> comprehensive unit tests.
>
> Refactoring, by definition, is changing the structure without changing
> the observable behavior.

IMO, that definition refers to a system, not individual objects. When
you change objects, you usually have to change the examples.

Keep in mind that that goes nearly unnoticed in java or .NET because
of the refactoring tools available on those platforms. Change a method
name once and it changes it everywhere, *including the examples*. Move
a method from one object to another and you get a dialog that let's
you opt to leave the existing method in place delegating to the new
location, or change all the consumers of that method in the system,
*including the examples*, to use the new location.

> Implicit in using tests to enable
> refactoring is the idea that those tests precisely define what the
> behavior of a system should be.

Not so much about precision as it is about comprehensiveness.

> If we say that our specs are not
> actual specifications of desired behavior, then specs aren't
> sufficient safety nets for refactoring.

Again - this word "specification" is causing trouble.

Examples have three different roles. When you first write them, they
are examples of how you want an object to behave. After you get them
to pass, they become both executable documents of the system as it is
and regression tests.

In their role as regression tests, they serve the same role as unit
tests do in refactoring.

> This mostly comes from my experience that refactoring is often a PITA
> when using mocks.  Mocks isolate dependencies, which is great, and
> makes it easy to change code without affecting parts of the system
> that really shouldn't be affected.  However they make simple, standard
> refactorings like "move method" more difficult.

Again - this is a solved problem in other platforms and will
eventually be solved in ours.

> If I say that stories are authoritative and specs aren't, then that
> means I ought to rely on stories to provide the safety net for my
> refactoring.  When taking those baby steps, it's important to keep the
> stories green rather than the specs.

On some level that makes sense - but it's going to slow you down quite
a bit when you start building up a significant suite of stories.

The way I've always dealt with this was to rely on the examples to get
me through a refactoring, and then run the stories before committing.
That allows me to stay focused on small problems and progress
steadily.

By the way, when I say "always dealt with this", I'm talking about
some years of experience using FitNesse for stories and xUnit for
examples. So although the Story Runner is new, the idea of having two
separate environments - one for system-level examples and one for
object-level examples - has been around for a while.

>  Another result of this thinking is that more specification should be
> done in stories than I originally thought.  Edge cases are my prime
> example.  I used to think I should write a story that expresses the
> general desired behavior, and then cover any edge cases in specs.

I think they should be covered in both stories and examples. The thing
is that they get covered in different ways.

For one, the language in which they are expressed is different -
because the stories are about the system and the examples are about
the objects in the system. And there will be some duplicated effort
between the stories and the examples - and that is a GOOD thing.

Additionally, when dealing with stories, you may specify that a
particular error message shows up on the screen. However, when you get
down to the individual objects, you would likely have a single example
showing that the screen will show whatever error message you throw at
it, and then move down to the model to generate this particular edge
case message.

> However edge cases should be covered by stories because stories define
> the desired behavior of the system.

Definitely!

> Also, edge cases presumably
> represent some business value to the customer.

Definitely!

> Finally, it's better
> to keep all of the desired behavior specs in one place.

Here's where we disagree. I think that it's a matter of who the
audience is for the different tools.

> Stories are
> naturally more verbose than specs though.
>
> That paragraph feels awkward to me, because I think I'm missing some
> vocabulary.  It suggests to me that the collection of all user stories
> is the app specification - "spec" for short.  What is the collection
> of all descriptions, the object-level specs?  I've always just said
> "specs," but I don't think that really fits anymore with my current
> thinking.  Not to mention it's just confusing if I also use "spec" to
> mean the collection of all user stories.  I know that an individual
> describe block is a "description," but maybe the whole suite should be
> called "descriptions" instead of "specs?"

The vocabulary that we seem to be moving to in the trunk is this:

Story Framework
- Stories
- Scenarios
- Steps

Example Framework
- ExampleGroups (what you referred to as descriptions)
- Examples

I'm not completely comfortable with this yet in terms of being able to
talk about it, so suggestions are welcome. The problem with using Spec
or Example is that either can easily refer to the coarse grained
stories or the fine grained object level examples. Maybe we should
call them Coarse Grained Examples and Fine Grained Examples :)
Seriously - I welcome other thoughts on this.

>
> What do you guys think?  Is it useful to draw a line and say that
> stories are authoritative and specs aren't?

I don't find this useful. To me they are two completely separate
animals that work together to describe the behaviour of a system. They
are equally authoritative (or not). They both have a life cycle in
which they move from examples of what we'd like to examples of what we
have.

> Do you think it becomes
> less crucial to use object-level specs to enable refactoring, and
> instead lean on stories more?

I think it's useful to use the stories as a periodic sanity check (as
I mentioned above), but I think that if you start using stories as
your safety net while you're in the rapid flow of refactoring, you're
begging for a significant drop in productivity. They're just going to
take to long to run and won't help you to isolate problems as they
arise.

Thanks for the thought provoking post!

Cheers,
David


More information about the rspec-users mailing list