BDD/Rails/Shoulda

This is a little off topic, but I use rSpec and I¹m starting to question
the
quality of my specs. In my research and attempt to learn how to write
better specs, I¹ve came across a few things that I¹d like to discuss.

I¹m having more and more difficulty understanding BDD. The more I read
and
the more I watch, the more questions I come up with. Let me just ask a
couple of general questions to start this off.

Is Œshoulda¹ actually following the principals of BDD? But, I guess
that¹s
not really a good question. Is Œshoulda¹ encouraging it¹s users to
follow
the principals of BDD? I see all of the macros like:

should_belong_to

should_require_attributes

To me, that is not BDD. Basically that¹s just testing whether or not
your
model contains a certain code fragment. But, that brings me to my next
question.

Is BDD even possible with Rails? (I think it is, but I ask myself that
more
and more lately)

I just picked a random model in the application I¹m currently working
on.
The ŒPicture¹ model. I use the attachment_fu plugin, which helps this
model
handle pictures (it creates thumbnails, validates sizes, etc.) I wiped
out
all the code I had and all the specs I had. I started from scratch:


class Picture < ActiveRecord::Base

end


The first piece of code I would write if I wasn¹t using BDD, would be:


class Picture < ActiveRecord::Base

validates_as_attachment

end


Which basically handles all of my validation. So, from a BDD
perspective,
how do I spec that? I know, I know, I should be writing the specs
first.
But, what do I do about these helpers that come with plugins. Do I
write a
spec:


describe Picture, Œwith a blank filename¹ do

before(:each) do
@picture = Picture.new valid_picture_attributes.except(:filename) #
This
uses some rSpec helpers
end

it do
@picture.should_not be_valid
end

end


So, the most simple way to solve that would be (this is part of what
Œvalidates_as_attachment¹ does):


class Picture < ActiveRecord::Base

validates_presence_of :filename

end


But, now what, I¹m going to reverse engineer this plugin¹s helper? I¹ll
just spec it all out and eventually refactor and put the
Œvalidates_as_attachment¹ back? Or, maybe since this is a plugins
helper I
don¹t even need to test any of this. It¹s the author of the plugin¹s
responsibility. This is were my brain enters an infinite loop (one
example
anyway, hehe). I just can¹t seem to nail down the workflow when specing
rails apps. I also have a hard time determining what to spec.

I know I asked a lot of questions, but basically I¹m just trying to find
out
if people are actually following the BDD principals strictly when
writing
Rails apps. If you are can you give me some insight in the above
example?

Thanks,

Matt L.

I’m not sure this answers your questions, but you prompted me to
share my experience.

Personally i consider BDD just one tool in my toolbox. And I consider
rspec to be as much a testing tool as a (BD)Development one. So I
often find myself just taking the path of least resistance. And
iterating.

In some cases it really ‘feels right’ to write the examples first and
then implement the code, repeat… I love doing that, the ‘BDD way’
is fun.

But half the time, I find myself working ‘the old fashioned way’ - I
write down (often with pen and paper, omg!) a list of things my code
needs to do, I implement it, test it manually in the browser or
console. After a point (not too much later though) I then go back and
write specs that verify my code and firm up my intent. I think this
is because Ruby and Rails can be so expressive in themselves (like
the plugins you mentioned). I’ve jokingly referred to this as DDB
(development driven behavior).

Importantly, when I code first, then spec, the spec phase is not an
‘afterthought’. Rather, the code can be thought of a first pass or
prototype, and the specs get me the firm up (or reevaluate) the
behavior and/or refactor my code. Bottom line – the process is
iterative.

In the end, both approaches leave me with quality code, expressive
specs, edge test cases, and regression tests.

Obviously I’m not speaking as a BDD priest, rather as a soldier in
the trenches.

linoj

Hi Matthew/Jonathan

On Apr 24, 2008, at 6:58 pm, Jonathan L. wrote:

I’m not sure this answers your questions, but you prompted me to
share my experience.

And this has prompted mine… I was going to do a blow-by-blow
response to Matthew’s post but I can probably sum up my current
thinking pretty quickly.

Personally i consider BDD just one tool in my toolbox.
+1
And I consider rspec to be as much a testing tool as a
(BD)Development one. So I often find myself just taking the path of
least resistance. And iterating.

In some cases it really ‘feels right’ to write the examples first
and then implement the code, repeat… I love doing that, the ‘BDD
way’ is fun.

+1 I think this is something to strive for, because if you get into
this rhythm you can enter BDD Flow™, and there’s nothing more
productive than story-spec-code-spec-code-spec-code
story-spec-code…

But half the time, I find myself working ‘the old fashioned way’ - I
write down (often with pen and paper, omg!) a list of things my code
needs to do, I implement it, test it manually in the browser or
console.

I find this happens most often when I’m doing something completely
new, or have no idea what the end result should be.

iterative.
When I do this I always comment out all the code I wrote, and write
specs that let me uncomment them. This way I never stopped doing BDD,
I merely had an irb session running in my app to play with ideas :slight_smile:
You should never ever ever leave code behind that you haven’t seen is
required by a spec, or you will slowly lull yourself into a false
sense of security.

In the end, both approaches leave me with quality code, expressive
specs, edge test cases, and regression tests.

Obviously I’m not speaking as a BDD priest, rather as a soldier in
the trenches.

Well priests used to be allowed to fight, just only with blunt
weapons :smiley: Or a bit less opaquely, I don’t think it’s necessarily a
Bad Thing when you don’t apply every single BDD/OOP/agile principle in
its textbook way. To do that in the face of Rails would involve you
being side tracked into facading or rewriting large chunks of code.
Coding with Rails is a bit like trying to get down a narrow corridor
with a hobbling old man in front of you, who wobbles in front of you
every time you try to squeeze past. The theory books didn’t foresee
this :slight_smile: And in that sense the BDD theory doesn’t apply, because BDD
is supposed to make you MORE productive.

When I wonder if I’m wasting time trying to get everything perfect
(and I am a bit neurotic about my code, so that’s my default state of
mind), I ask myself:

  • is there any realistic thing I could change that would silently
    break my code?
    and
  • if I come back to this code later to change/add new features, will I
    spend more time understanding and refactoring it than doing the actual
    upgrade?

If the answer is no then I feel like I’ve applied BDD well enough.

I also liken it in my head to the tai chi saying “no shape, no form”.
This basically says that no matter how many years you spend doing the
same training routines over and over, when you actually come to fight
you use what you need, how you need to. I try and avoid saying things
like this in front of people new to BDD because it could be taken (as
it is with bad martial artists) to mean you don’t need to spend years
learning theories and good practice, and you can do what the hell you
like. Well, take a look round most kung fu clubs and most tin pot
development shops and you will see the exact same thing - people that
believe “all that theory is a waste of time, we just do practical
stuff here”. I’m sure everyone on rspec-users knows what that really
means.

Ashley

PS apparently I lied in my first line, I couldn’t sum up my thoughts
quickly - however an abridged version minus the vitriolic ranting is
available on demand :smiley:


http://www.patchspace.co.uk/

On Thu, Apr 24, 2008 at 3:57 PM, Ashley M.
[email protected] wrote:

way’ is fun.
needs to do, I implement it, test it manually in the browser or
plugins you mentioned). I’ve jokingly referred to this as DDB
I merely had an irb session running in my app to play with ideas :slight_smile:
the trenches.
is supposed to make you MORE productive.
upgrade?
like. Well, take a look round most kung fu clubs and most tin pot
development shops and you will see the exact same thing - people that
believe “all that theory is a waste of time, we just do practical
stuff here”. I’m sure everyone on rspec-users knows what that really
means.
This reminds me of Allister Cockburn’s application of Shu Ha Ri in
software development.
Coming Soon – Alistair Cockburn
ShuHaRi
http://c2.com/cgi/wiki?ShuHaRi

Hi Matthew.

I don’t think it’s off-topic at all. I would estimate around 80% of the
traffic on this list is about “how do I test such-and-such with rails?”.

Rails is designed for a particular subset of web applications, namely
ones
that look a lot like basecamp. They mostly involve capturing, updating
or
presenting data, in a very two-tier, database-on-the-screen kind of way.
The
giveaway is having ActiveRecord as the persistence layer. The other clue
is
in the fact that you have to define a database before you can fire it up
and
get the “you’re on rails” welcome page. All the examples and tutorials
I’ve
seen (outside of the rspec world) start by defining database tables and
their corresponding ActiveRecord classes, and then building up the
application from there.

I describe these applications as being mostly surface area (i.e. front
end
and back end), with very little volume (i.e. interesting behaviour other
than CRUD and presentation). Now don’t get me wrong, you can do a lot
with
these kinds of applications, and they are incredibly useful. In fact
most
“enterprise” applications are simply variations on this theme. But the
rails
stack simply isn’t geared up for outside-in development, or, I would
venture
to say, for many of the applications it is being targeted at.

I presented rspec and rails in a session with David C. and Aslak
at
last year’s RailsConf Europe and I was amazed at how brilliantly David
and
Aslak had beaten rails into submission in order to present an
outside-in,
view-first approach to developing an application. I would never have
thought
of the approach they came up with - I would have given up in despair
long
before that!

The tight coupling between the domain object classes and the persistence
mechanism means you either have to mock domain objects - which simply
doesn’t make any sense for anaemic data-only objects - or couple every
example to your database, and life’s too short to have a 30 minute build
for
a web app.

So now you have one of two options. Firsly, you can accept that rails is
designed for large surface area applications, and be prepared to
compromise
on testability and the ability to do outside-in development. The other
is to
use a different ruby web stack such as ramaze (http://ramaze.net) which
allows you to start at the outside and work inwards, evolving separate
views, controllers and models as you need to (and only when you need
to).
Side note: I just noticed that when you run ramaze --create blah, you
get a
spec directory with some simple “GET / should return 200” specs. And not
a
database in sight. Sweet!

Cheers,
Dan

ps. I’ll be turning this into a longer and more detailed rant on my blog
soon :slight_smile:

2008/4/24 Matthew L. [email protected]:

On 25 Apr 2008, at 00:59, Brian T. wrote:

This reminds me of Allister Cockburn’s application of Shu Ha Ri in
software development.
Coming Soon – Alistair Cockburn
ShuHaRi
http://c2.com/cgi/wiki?ShuHaRi

Hadn’t seen that before. I’ve only studied chinese arts so hadn’t
heard the expression before, the idea is the same though.

Thanks for the links, the first one especially looks really interesting

Ashley


http://www.patchspace.co.uk/

On Apr 24, 2008, at 5:57 PM, Ashley M. wrote:

Personally i consider BDD just one tool in my toolbox.
this rhythm you can enter BDD Flow™, and there’s nothing more
new, or have no idea what the end result should be.
prototype, and the specs get me the firm up (or reevaluate) the
behavior and/or refactor my code. Bottom line – the process is
iterative.

When I do this I always comment out all the code I wrote, and write
specs that let me uncomment them. This way I never stopped doing BDD,
I merely had an irb session running in my app to play with ideas :slight_smile:

TDD purists will tell you to delete the prototype code and start over
once you’ve learned what you need to from the process of prototyping.
One of the amazing benefits of TDD is that you generally end up with
better APIs than you do backfilling tests against existing code.
Commented prototype code is still code that was created before the
tests and looses that benefit.

Also, this approach increases the level of granularity from individual
messages to complete statements. For example, let’s say I have this
line commented:

do_something if this_condition and that_condition

If this_condition and that_condition always return the same boolean
value, there is no need for a test for that_condition to exist. Nor
should it exist without having been driven into existence by an example.

So the approach of uncommenting prototype code still leaves you with
code that is less clean, if only slightly, than code which is purely
driven out by examples.

Cheers,
David

On Sun, Apr 27, 2008 at 10:05 AM, Dan N. [email protected] wrote:

get the “you’re on rails” welcome page. All the examples and tutorials I’ve
to say, for many of the applications it is being targeted at.
doesn’t make any sense for anaemic data-only objects - or couple every
spec directory with some simple “GET / should return 200” specs. And not a
database in sight. Sweet!

Cheers,
Dan

ps. I’ll be turning this into a longer and more detailed rant on my blog
soon :slight_smile:

Please do. I’d especially like to know more about outside-in style you
mentioned. Rails is my first experience with web development and I
don’t have a good intuitive notion of what that different approach
would be. Send me (us?) the link when it’s done :slight_smile:

Cheers,

Helder

Thanks for all of the great replies!

This thread answered a lot of my questions.

-Matt

On 28 Apr 2008, at 07:17, David C. wrote:

So the approach of uncommenting prototype code still leaves you with
code that is less clean, if only slightly, than code which is purely
driven out by examples.

Hmm, I have never found this in practice. In fact, about a month ago
I was working on someone else’s code and followed this process of
uncommenting code as I wrote the specs for it (there were none for
that class). I actually removed the ‘if this_condition and
that_condition’ part of a line that follows the pattern you gave above.

I don’t see how you could end up with redundant code following this
process. Perhaps I am doing something different that I didn’t
explain. Maybe it’s because I am blanking out what the code says when
I write the specs? I don’t know, but I haven’t found the problem you
describe above.

Ashley


http://www.patchspace.co.uk/

On 2 May 2008, at 06:13, Tero T. wrote:

I can well imagine how you may end up not getting all the advantages
of BDD thru uncommenting process when you compare to clean BDD. But
uncommenting is definitely better than writing spec on top of existing
code, which in turn is way better than not writing spec at all.

Perhaps “uncommenting” is a bad description. What I do is write specs
for the behaviour I want, and see what bits of the code (if any) do
that. (Which will obviously be pretty similar to the what it does
anyway.) What I don’t do is pick a line of code and write a spec
for it so I can uncomment it. I guess that’s how you would run into
trouble.

Ashley


http://www.patchspace.co.uk/

2008-04-30 15:51, Ashley M.:

about a month ago I was working on someone else’s code and followed
this process of uncommenting code as I wrote the specs for it (there
were none for that class). I actually removed the ‘if
this_condition and that_condition’ part of a line that follows the
pattern you gave above.

Maybe the fact that the code was not yours makes a difference here?
Dunnot, but I’d expect it to.

I don’t see how you could end up with redundant code following this
process.

I can well imagine how you may end up not getting all the advantages
of BDD thru uncommenting process when you compare to clean BDD. But
uncommenting is definitely better than writing spec on top of existing
code, which in turn is way better than not writing spec at all.

Maybe it’s because I am blanking out what the code says when I write
the specs?

Lucky you if you are able to do that. I’ve noticed I’m not.

Even when working test/spec-first, when I’m pairing with someone who
isn’t
experienced working that way, I find myself constantly saying “I’m
pretty
sure we don’t need that yet.” (I’ve just written the spec my pair is
trying
to get passing, so I know how little code we need.) If it happens then,
it
will certainly happen when that same developer is uncommenting code
already
written.

Out of curiosity, Ashley, what size team are you working with where you
don’t see this problem?
-hume.

On Fri, May 2, 2008 at 12:06 PM, Ashley M.
[email protected]

On May 3, 2008, at 11:07 AM, John D. Hume wrote:

Even when working test/spec-first, when I’m pairing with someone who
isn’t experienced working that way, I find myself constantly saying
“I’m pretty sure we don’t need that yet.” (I’ve just written the
spec my pair is trying to get passing, so I know how little code we
need.) If it happens then, it will certainly happen when that same
developer is uncommenting code already written.

Out of curiosity, Ashley, what size team are you working with where
you don’t see this problem?
-hume.

I remember a joke that Aslak mentioned a while back ago on this list:
He had a friend (or co-worker) who wanted to write a tool which would
delete every line of code which didn’t get covered with rcov. I found
that remark funny because Aslak didn’t know if his co-worker was
joking or not.

Now that I think about it more, it probably wouldn’t be a bad idea to
have such a tool like this, even if it was just for didactic purposes.

Scott

On May 3, 2008, at 4:01 PM, Scott T. wrote:

I remember a joke that Aslak mentioned a while back ago on this
list: He had a friend (or co-worker) who wanted to write a tool
which would delete every line of code which didn’t get covered with
rcov. I found that remark funny because Aslak didn’t know if his co-
worker was joking or not.

I think you’ve got the story mixed up a bit here. Aslak DID write a
tool called Guantanamo that does just what you propose, for java, not
Ruby: http://docs.codehaus.org/display/ASH/Guantanamo