Testing my patience. A skeptic’s thoughts on beginning to write tests
January 29th, 2009 by Benjamin Wagaman.Categorized as Ruby on Rails, programming.
It’s been a long time since I posted anything in my blog, so I thought I ought to break the silence. Lately, I’ve been trying to get myself caught up on the test-driven/behavior-driven development philosophy. If you are a programmer, maybe you can relate to my struggles of learning how to get it right.
Test-Driven Development is a programming philosophy that encourages the developer to specify test test conditions before writing the code to meet the specification. To me, this is counter-intuitive. I guess I am naturally a brute and think the best way to figure something out is to play with it, and than after a while it should just work.
Ironically, the chapter on Testing in the Agile Web Development with Rails book comes well after the first attempts at hammering out Rails code for a shopping cart application. I understand why the book is written the way that it is, and am greatly appreciative of the book, but there ought to be a Test-Driven version of the same tutorial, so that people can see first-hand how to test-first in development.
It also hasn’t helped that my first attempt at writing tests have been less than perfect too. I’ll end up writing 6 or 7 lines of test code to test one case for a method. The verboseness of tests has negatively reinforced me in to thinking that testing is hard.
What’s more frustrating is that I’ve heard expert developers talk about only having a line or two of test code to test a method. This has seemed to me to be an unatainable ideal. How are you supposed to test code that is ten lines long (or more) with one or two lines of test code? That’s unpossible.
But, recently I came to the realization that if the methods I am writing are smaller and do more specific things, then they are a whole lot easier to test. This is mostly because the tests can move towards the ideal of the expert: short, meaningful, specifications. This in turn helps me to actually write the test first, because I know I can specify the behavior of code that is less complex.
Some of the recent developments in RSpec have helped this ideal even further. For instance, see David Chelimsky’s post on RSpec 1.1.12 He notes that what you could have done
In order to test this:
class Person
validates_presence_of :email
end
You would have in previous versions of RSpec written:
describe Person do
it "should validate presence of email" do
person = Person.new(:email => nil)
person.should_not be_valid
person.should have(1).error_on(:email)
end
end
In RSpec 1.1.12, you can reduce this down to the following:
describe Person do
it { should validate_presence_of(:email) }
end
This is due to:
- an implicit receiver from the describe block Person.new
- custom matchers for validate_presence_of (which are available through plugins like rspec-on-rails-matchers or you can make your own matchers
- self commenting specification code
Three lines of code. Three lines of test. That’s pretty darn cool. Perhaps, it’s not possible to have a line by line spec for everything, but this is a lot better than before.
I’ve still got a fair bit of inertia to overcome before I’ve got TDD under my belt. The more I tell myself that test-driven development is less about testing than it is about developing well-written code, the more motivated I am to do it. I hope this is an encouragement to unit testing newbies.
RSS Feed