[rspec-users] RSpec makes me want to write better code

Zach Dennis zach.dennis at gmail.com
Tue Mar 31 13:10:44 EDT 2009


On Tue, Mar 31, 2009 at 5:39 AM, Fernando Perez <lists at ruby-forum.com> wrote:
> Fernando Perez wrote:
>> Hi,
>>
>> Today is a big day. I officially transitioned from manually testing by
>> clicking around in my app, to automated testing with RSpec + Autotest.
>
> 6 months since my initial post, what happened in between?
>
> - My controllers are getting anorexic, and that's good. An action
> typically does only 1 call to a model and behind the scenes that model
> will make other calls to other models and do some fancy stuff, this used
> to happen in the controller which was bad. Now it has become so easy to
> write model specs.

Great! Keeping controllers simple makes life better on many fronts.

>
> - I don't spec controllers, because it's too painful to do. I don't spec
> views either, because I tweak them too often, and it would take me more
> time rewriting view specs then actually coding the views. If there is
> something to test for is the rendering of the css across browsers,
> because that's terrible!

I usually let Cucumber run through the basics of the action, but I
write controller specs for interesting thing that affect the behaviour
of an action such as requiring logic, or a certain permission, or
special error handling logic, etc. Pulling these things out into a
controller macro makes re-using them extremely simple. The next beta
release for The RSpec Book will cover doing that.

I write view specs because they *change* so much. I don't spec the
structure of the page, just the semantics of it as it pertains to
information I programmatically display or don't display. IME, when
apps are small there is a feeling that Cucumber can do it all, but as
the app grows Cucumber can be a burden as well. Cucumber scenarios
can't do it all, and when you have interesting apps, hundreds of
scenarios and hundreds of steps it becomes way too time consuming to
try to find exactly what and why things died and why. I prefer focused
view specs for this regression rather than simply relying on Cucumber.
 Also cucumber step definitions can become large and unwieldy. I like
focused steps which do enough to prove a scenario works as expected
and I like to drop down to specs for the details of it.

>
> - I use cucumber+webrat to test that some important public pages render
> without a 500 error. I don't care if the view has such div except if it
> is a critical one. What I mean is that I won't test, all the assignments
> that should be on the page, as some tutorials demonstrate. This is
> nearly impossible to maintain.

I disagree with the last two sentences here. I build my views spec
first with examples that expect the result of "project.name" to be on
the page. Only then do I actually add it to the view. I have had no
issue maintaining this. Not only do I get a design benefit when its
not just a simple model attribute, but perhaps a calculated field, I
also get regression for free. I move swiftly, happily, and confidently
on without worrying about manually verifying everything on the page is
as it should be, I let my specs do that.

>
> - I can refactor my code, immediately spot areas where my code got
> broken, and fix it. Before some parts of my app would be broken without
> having me knowing about it for a long time until some cool customers
> report a few bugs, but this was not an acceptable situation.

IMO, this is the case when people don't write view specs. Unless
someone's Cucumber scenario covers everything on the view (which they
don't unless its a super simple CRUD app). Half the time I wonder if
people even know if their views are displaying the write things on the
page over time. How would they not know w/o specs? Do they manually
verify every page every time they deploy? That seems impossible to
maintain.

>
> - I don't use Autotest, it sucks too much power, and it is too much
> distracting. From time to time I run specs to check if things look good,
> and always before updating the code on the server.

Agreed. I loathe autotest, but I don't run specs time to time, I run
my specs all the time. It's a part of my development process. Red
Green Refactor. It's not just a mantra, its a discipline. Although
when I don't know what I want or need to do, I spike something
(without any tests), and once I figure it out I scrape the spike (or
comment it out) and drive it with examples.

>
> - I have written my own Factory. It's not OOP, it could be refactored,
> but it works 100% as advertised, provides default values, can handle
> associations, etc. I am pleased with it (I tried factory girl,
> machinist, etc and got pissed off). I encourage anyone to write his own
> little factory, to get a better hang of how to write good specs. I
> totally got mad with fixtures, it is impossible to maintain specs/tests
> with fixtures. Impossible.

Cool. Is it on github? I wrote my own as well, but then switched to
FactoryGirl because everyone I talked to loved it, but now I wonder if
they really loved it (or how much they actually use it) because it
works for about 80% of the things I need, and fails horribly for the
other 20%. I want to try Machinist next, but I'm sad to see you had
bad experiences with it. :(

And I hate the idea behind ObjectDaddy, adding methods to the model to
generate spec data. Gross.

> - I don't do true BDD, i.e: I still write code before specs, because
> that's what motivates me. I consider that seeing my app living and
> writing code for my app more important than writing specs. Specs are
> still important, but only as a bug reporting tool, they don't add any
> value for the customer. In this crisis If I wanted an employee to resign
> by himself without paying him benefits (that's how it works in Europe),
> I would make him write specs all day long, and forbid him from seeing
> the app and play with it. He wouldn't last 1 week doing this.
>
> What about you?
>

You've probably seen this, but it never gets old, "Testing is for
testers." When you focus on specs solely for the benefit of testing
then you are only getting the tip of the ice berg. Traditional "tests"
are really they to provide safeguard against regression. This is a
secondary benefit to BDD. BDD is about driving your app from the
outside in, focusing on the behaviour at different levels.

For example, Cucumber lets you focus on the app behaviour, while view
specs lets you focus on the expected behaviour of a view (to display
"project.name"), and controller specs let you focus on the behaviour
of a controller (such that only "admins" can destroy a project), and
model specs let you provide examples for how it should be working.
Focusing on the behaviour at these different levels forces you to
write better designed code, more focused objects, simpler controllers,
just-the-right size models, etc.

A better design lets you move fluidly through the app as it evolves
and changes. When you use BDD, you get a better design as a part of
the process. As a nice secondary benefit you get protection against
unwanted regression.

I encourage you and anyone else to practice your BDD more. The more I
practice the more fluently I can drive my app with examples form the
outside-in, and the more capable I am to know when to write a
controller spec and when not to---and it's not based on if it takes
too long. The decision is based on experience for knowing how-to do
it, and how-to do it well, and then asking myself, "Does this get me
anything?"

Not spe'cing something because you don't know how-to spec it well is
most likely not an issue with BDD. It's a skill deficiency with the
developer. The only way to make good decisions it practice and become
more familiar with your tools. Then you will start making informed
decisions that add value to your project. The alternative is that you
make uninformed decisions and you or other developers will suffer down
the road because you made a bad decision but didn't know it because
you lacked the knowledge and/or experience to know it was a bad
decision.


>
> Best regards,
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>



-- 
Zach Dennis
http://www.continuousthinking.com
http://www.mutuallyhuman.com


More information about the rspec-users mailing list