From time to time I end up in a discussion (as often as not with myself) about the point at which something is so trivial that it doesn’t justify creating a unit test (or behaviour spec, in more BDD-like language).
The latest incarnation of this question arose while starting work on a Ruby on Rails app1. Rails has what I like2 to call this duck configuration (if it walks like configuration and quacks like configuration…). It looks like config, but it’s implemented as method calls. Validations are one example:
class User < ActiveRecord::Base
validates_presence_of :username, :message => ‘is required’
Here’s the spec (following the style demonstrated by Luke Redpath) that caused that line to be written:
context “A user” do
@user = User.new
specify “should be invalid without a username” do
@user.attributes = valid_user_attributes.except(:username)
@user.errors.on(:username).should == “is required”
Aside: the example above doesn’t follow One Expectation per Example – should the error message be in a separate spec? I’m inclined to think that would be overkill, but I’d like to hear your opinion.
Eagle-eyed readers might have noticed that the spec is significantly longer than the code itself. It’s only configuration, after all – does it really need a spec? I’m inclined to say yes.
Firstly, there’s a slippery slope here. If this line of code is too trivial to write using TDD/BDD, maybe so’s that small helper method, or that exception handler. Before you know it, you’re drifting back into the bad old ways of writing the code first, then adding tests afterwards when you think it’s necessary.
The other reason is that test-driven development is a kind of double-entry bookkeeping. Every piece of behaviour you create has a test/spec in one ledger, and an implementation in another, and every time you run your test suite, you’re balancing your books. If the required behaviour changes later, you rewrite the spec and adjust the implementation to match. You probably aren’t going to have auditors looking over your code, but you will have future developers (including yourself, long after you’ve forgotten writing the code), and they’ll appreciate the clarity of intent that full specifications3 provide.