[rspec-users] BDD/Rails/Shoulda

Dan North tastapod at gmail.com
Sun Apr 27 09:05:53 EDT 2008


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 Chelimsky 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 :)


2008/4/24 Matthew Lins <mattlins at gmail.com>:

>  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 Lins
>
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20080427/e3c94468/attachment.html>


More information about the rspec-users mailing list