How to write the very first example?

Many posts on this list are about using RSpec with Rails and that’s the
way
I’m also using RSpec all the time.
Unfortunately there isn’t that much info about using RSpec for
standalone
Ruby projects.
I must admit I’m really having a hard time writing the very first
example(s)
for a fresh standalone Ruby project. I haven’t really got a clue where
to
start, how to call the first example and how to describe it.
I want to use the outside-in approach, but that suggests the first
example
you write should specify the workings of the whole project, right?
I alway catch myself focusing on dependancies and start from the inside
instead of the outside. (if I implement this first, I can use it as a
building brick for that feature, and if that feature is implemented I
can
work on that other feature.)

So, where do I actually need to start?

Thanks for clearing things up Pat!I’ll give the story stuff I try, I
haven’t
looked at it yet.

Does this actually mean I need to start describing some stories, then
start
with writing the examples/code for the first story by using mock objects
for
every layer?
Do I eventually need to replace all the mocks by real objects?
And is it bad to do partially stubbing on objects, or does this indicate
an
object should provide more information about its state?

For instance, take a look at this pastie http://pastie.caboo.se/102174,
is
this a good way to write an example for a behaviour or am I taking a
wrong
approach?

I feel the need for some small, simple, clean example programs, to take
a
look through.
Maybe, I just need to put my current pet project online and let people
shoot
at it.

  • Matthijs

On 9/29/07, Matthijs L. [email protected] wrote:

Many posts on this list are about using RSpec with Rails and that’s the way
I’m also using RSpec all the time.
Unfortunately there isn’t that much info about using RSpec for standalone
Ruby projects.

I don’t think that matters much, the principles are the same. You
write stories for features, and write specs to drive object
implementation. In fact I would say that Rails presents some unique
challenges for BDDing, and that a “pure” ruby project is easier!

I must admit I’m really having a hard time writing the very first example(s)
for a fresh standalone Ruby project. I haven’t really got a clue where to
start, how to call the first example and how to describe it.

Begin at the beginning :stuck_out_tongue:

There are a couple approaches. First thing I would do is write a
story for one feature you want in the system. Having that story means
that you stay focused on one particular task and building the
infrastructure that will be used. I actually wrote a blog post a
while back on what I call “design deep, not wide” [1]

On a simpler level, stories represent real progress. When you’re done
with a story you should have actual value, and that is fulfilling and
motivating.

Also, you can start with smaller stories and build out from there. In
Dan N.'s article about introducing rbehave [2] he works with simple
objects instead of a full application stack like you might in Rails.
When I first read it, I thought a standard spec might be more
appropriate. Once it hit me though (which was a couple months later),
I fell in love with that approach.

To give you an idea, here’s the starting code:

Story “transfer to cash account”,
%(As a savings account holder
I want to transfer money from my savings account
So that I can get cash easily from an ATM) do

Scenario “savings account is in credit” do
Given “my savings account balance is”, 100
Given “my cash account balance is”, 10
When “I transfer”, 20
Then “my savings account balance should be”, 80
Then “my cash account balance should be”, 30
end

Scenario “savings account is overdrawn” do
Given “my savings account balance is”, -20
Given “my cash account balance is”, 10
When “I transfer”, 20
Then “my savings account balance should be”, -20
Then “my cash account balance should be”, 10
end
end

Eventually he sticks objects in there as he implements them, but at
least at the very beginning there’s no code to speak of. It’s just a
user story. The beauty of it is that all you’re doing is specifying
acceptance criteria - what it means to be “done.” One scary part of
doing lower level specs is on some level you’re designing code without
any real sense of direction. You might not necessarily know what
objects you need. While specs are excellent for discovering the
behavior of objects, as far as what operations they perform and
interactions they have, they don’t do much to help with the desired
behavior of the system.

So, basically, writing stories forces you to think about what you want
to achieve, and gives you a clear way to measure progress. You know
where you want to end, and you know all the steps it takes to get
there, and that gives you the knowledge of where to start.

I want to use the outside-in approach, but that suggests the first example
you write should specify the workings of the whole project, right?
I alway catch myself focusing on dependancies and start from the inside
instead of the outside. (if I implement this first, I can use it as a
building brick for that feature, and if that feature is implemented I can
work on that other feature.)

This is where mock objects yield their greatest benefits. A lot of
people think mock objects are good only for isolating expensive
resources, but they’re fantastic in allowing you to design well in
chunks. For example, something as simple as:

customer.place_order some_item, 12

Will require that I have a customer class, a place_order method, an
item class, and probably an order class somewhere. I’m adding a
little feature, and all of a sudden I have to implement all these
classes, at least in bits, and because I’m only handling a little bit
of the behavior I don’t have any idea how they’re going to be used in
other parts of the system. It’s scary because there’s more pressure
to get it right the first time.

mocks, otoh, allow you to defer all of that until later. When working
on a feature, I can concern myself only with that feature and not
worry about all the plumbing that it may need. A couple things happen
there

  1. I tend to end up with a clean, layered architecture. This happens
    because I’m only working on one layer at a time. When I’m bouncing
    back and forth between layers, I have to be extra mindful of what I’m
    dealing with, otherwise stuff that should be in one layer creeps into
    another and now I’ve got a muddled, difficult to understand design.
  2. My life is easier! With mocks, I can isolate my thinking to a
    certain level or chunk of the code. Instead of pushing and popping
    all kinds of stuff on my mental stack, I limit the number of little
    things I need to think about at one time. I wasn’t blessed with
    unlimited brain space, so that’s a huge win for me. It also creates
    extra room to think about what I’m doing at a higher level and keep
    everything in perspective.

It’s interesting, because your questions really boil down to being
overwhelmed with what you have to do. It’s a feeling I know all too
well. Fortunately RSpec provides two tools that do a fantastic job in
easing the uncertainty. First you have user stories which help give
you direction in the project. You know what you want to get done,
have a good measure of progress as you implement it, and finally have
a clear understanding of when you’ve completed it. On a lower level,
mock objects help keep your thinking focused instead of running off in
all different directions writing the all the infrastructure that it
may take to write one line of code. You become less likely to code
yourself into a corner, and you keep your mental stack in check.

I hope that was helpful. I completely understand sitting at the
keyboard wondering just what the hell I should be doing. I’ve found
that RSpec helps me out a great deal both in terms of capturing
desired business outcomes and in implementing the code to achieve
them. It can take a while to really get it, but you may come to find
that once you do you’re hooked.

Pat

[1] http://evang.eli.st/blog/2006/12/18/design-deep-not-wide
[2] http://dannorth.net/2007/06/introducing-rbehave

On Sep 29, 2007, at 5:43 PM, Matthijs L. wrote:

example you write should specify the workings of the whole project,
right?
I alway catch myself focusing on dependancies and start from the
inside instead of the outside. (if I implement this first, I can
use it as a building brick for that feature, and if that feature is
implemented I can work on that other feature.)

So, where do I actually need to start?

I sympathize with your position. I imagine it’s much easier now that
the story/rbehave stuff is around.

In the past what I’ve done is written a prototype (usually a
functioning one) - and have done it code-first, with no tests
whatsoever. (I’m also thinking of Paul Graham’s words - all large
programs start as small programs/scripts). Once I have that
prototype, I rewrite the code, this time going test first, and making
it Object Oriented. If I ever need to refer back to that old code, I
can, but, at the same time, now I have written something slightly
different, which is architectured better, and has tests to back it up.

Just to give you an example of this, a few months ago I wrote a
backup system. The core of it was just using rsync - very much like
a simple script. But soon I wanted much more - backup deletion which
would happen automatically, based on rules specified in a DSL. So I
rewrote the core of the system test first, and was then able to layer
the rest of the features on top and around that.

Going on the 37 signals mantra: What is the most important feature of
the system? That’s what you should be writing specs for. They may
happen to be quite high level - that’s what your stories are for.
Write one story (or a high level spec which you can mark as
“pending”), and drill deeper into that, writing specs for the modules/
classes that it will take to make that initial story going.

Hope that helps,

Scott

On 9/30/07, Matthijs L. [email protected] wrote:

Thanks for clearing things up Pat!
I’ll give the story stuff I try, I haven’t looked at it yet.

Does this actually mean I need to start describing some stories, then start
with writing the examples/code for the first story by using mock objects for
every layer?

Here’s how I do this. I start with a set of stories and scenarios
expressed only in text (no code in the Given/When/Then steps). I pick
a scenario to start with and fill in the code, writing the code I wish
I could write as I go. This helps me to discover the outermost objects
and their APIs.

Next, I pick one of the objects from the story and start driving it
out with examples. The first examples will often overlap a bit with
the stories and this is OK. Even expected.

For anything that is needed by the object I’m working on at any given
moment, if the code already exists to support it and using it is not
expensive (in terms of required setup or processing cycles) I’ll use
it. If the code is not there yet, or it is expensive to use, I’ll
introduce a mock.

Do I eventually need to replace all the mocks by real objects?

You don’t ever need to replace the mocks with the real objects, but
you certainly can. The reason you don’t need to is that the
Stories/Scenarios will fail when there is a mismatch between a mocked
object and the real object.

As to whether you should replace them, there are several schools of
thought that generally resolve around responsibility and behaviour.
For example, if we call foo.validate and that, in turn, calls
validator.validate(self), where is the responsibility for validation?
Some say it is foo’s responsibility, some say it belongs to the
validator. That debate is out of scope for this discussion, but there
are plenty of other discussions on this list that you can mine for
ideas about this.

Another factor that comes into play is the level of complexity of the
setup. If you have to mock 3 layers deep, then maybe it’s better to
use the real object. Of course, if you have to mock 3 layers deep,
there might be a design problem.

And is it bad to do partially stubbing on objects, or does this indicate an
object should provide more information about its state?

Well, it’s always better if you can avoid revealing information about
state. Tell, Don’t Ask. But sometimes it is a necessary (or at least
very useful) evil. And even when you’re just telling (i.e. no
state-exposure necessary) the same question might come up.

It really depends on context. I think it’s reasonable to ask that
question whenever you’re using partial mocking/stubbing. Sometimes the
answer is going to be that the object should respond to some new
message, sometimes not.

For instance, take a look at this pastie http://pastie.caboo.se/102174, is
this a good way to write an example for a behaviour or am I taking a wrong
approach?

In the text above the code under development, it says “Read the
repositories from a file, notify the user for updates in all
repositories,” but the example says “should call notify_if_updates on
every repository.” This is pretty interesting, because the example
uses an implementation-specific description, whereas the comment
describes behaviour at a higher, more abstract level. So I’d start by
changing the example to read “should notify the user if there is an
update in any repository”, with another example (likely several
others) that reads “should not notify the user if there are no updates
to any repository”.

Of course, this starts me thinking that notifying the user is really
not Base’s responsibility, and that notify_if_updates should accept a
notifier, listener, callback, etc. at which point the example is
“should provide a callback to each repository to use if the repository
has updates.”

So, the feeling I get from looking at this particular example/code is
that it started from the code, not the example. I could be wrong -
that’s just how it feels to me.

I feel the need for some small, simple, clean example programs, to take a
look through.
Maybe, I just need to put my current pet project online and let people shoot
at it.

That would certainly be a powerful learning experience for you if you
have the stomach to absorb criticism that is only sometimes
constructive. It would probably be so for all of us.

One thing to keep in mind if you do this experiment is that BDD is a
process, and you’ll be showing and getting feedback on a result. There
is something to be learned from the result, but the real money is in
the process, so you’ll have to do some extrapolating from the
criticism and apply it back to the process - unless of course you want
to turn it into a complete tutorial with step by step explanations of
every decision you made along the way. I can tell you from experience
that it is a LOT of work :wink:

Cheers,
David

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