Testing and behavior in development
I’ve been practicing test driven development on some percentage of my projects for a while now. Something, however, has always felt just a little bit tiring about the whole thing. The biggest thing I struggled with was what to test, and how best to test. I suppose that’s obvious, eh? My biggest failing was that I would often test things that don’t need testing; things like other people’s heavily tested frameworks. This made writing tests boring.
Then, I read Dave Astel’s posting on behavior driven development, and a lightbulb—dim though it may be—went off in my head. The problem with TDD isn’t the idea, but the perspective. Dave makes it clear in the following excerpt.
It’s about figuring out what you are trying to do before you run off half-cocked to try to do it. You write a specification that nails down a small aspect of behaviour in a concise, unambiguous, and executable form. It’s that simple. Does that mean you write tests? No. It means you write specifications of what your code will have to do. It means you specify the behaviour of your code ahead of time. But not far ahead of time. In fact, just before you write the code is best because that’s when you have as much information at hand as you will up to that point. Like well done TDD, you work in tiny increments… specifying one small aspect of behaviour at a time, then implementing it.
When you realize that it’s all about specifying behaviour and not writing tests, your point of view shifts. Suddenly the idea of having a Test class for each of your production classes is rediculously limiting. And the thought of testing each of your methods with its own test method (in a 1-1 relationship) will have you rolling on the floor laughing.
Eureka! Behavior Driven Development. Really what was missing was the context of everything. So, I went searching the treasure-trove that is Google, and came across an article by Luke Redpath that put it in a Ruby on Rails perspective. Specifically, the behavior of Models and how to specify them. That then led me to RSpec, which implements a DSL for writing specifications that is on top of the normal Test::Unit framework. There’s also a Ruby plugin that helps make things work smoothly.
Now, if only ZenTest worked with Specs. The auto_test piece would be very useful.
Updated (21 Oct 2006): Nick Sieger has done this already, apparently using his magical time machine.
This entry was posted at 12:50 pm on 16 October 2006 and is filed under Programming. You can follow any responses to this entry through the post-specific RSS 2.0 feed.
It’s interesting, in that I think DocTest is an interesting approach to the problem. I don’t know if it works for most people, but it certainly is a great way to do more “documentation.” The problem that it presents is that it requires relatively “simple” situations, in my experience, where-as something like RSpec allows for much more complex assertions and setups. I think DocTest is a start, but Specifications are a better way to rough up the edge-cases.
Responses are currently closed, but you can trackback from your own site.
Python has had this for a while in the form of Doc Tests. Doc Tests are nice because they encourage documentation. Instead of the cryptic assertions buried in a unit test somewhere you have something that should be humanly readable right there in or near the source. I love having that as an option now – knowing that I can write some API documentation with examples, and that those examples actually work. If I change the code the behavior, I have to change the documentation to reflect that.
It’s still possible to write very cryptic doc tests that aren’t much good to end users as documentation, but they still tend to be easier to read than Unit Tests.