Tests as tours


I've discovered something quite amazing this week; something quite simple that shouldn't really have been much of a surprise, but it was.

If you have a substantial set of unit tests then you can use them as the backdrop for documentation that tours the code base in a controlled and manageable way. Kinda like a sing-along, the reader can be directed through several key tests in a debugger whilst the document describes what's going on and reasoning behind some of design decisions.

This seems to work best with a fairly high level unit test; something that tests an object that uses lots of other real objects, rather than just mocks, to do stuff. I've been trying this out this week with an object which is pretty much the "above" in our system's "parameterise from above" pattern. This object pulls 90% of the system together but is still pluggable for the external data sources; so it can be tested reliably in isolation.

It's actually quite educational to walk through a complex system under test and explain how it works and why it's like that; hopefully in a way that people can understand even if they're not currently intimate with the system. I fixed a few bugs en-route, I guess they were more design bugs than execution bugs, but when you find yourself wondering why, exactly, does it do it like that; there's usually a chance to refactor to something simpler.

Next on the list is one of the major sections of functionality that was pluggable in the object that I've just done a walk through for. This was mocked up in the story of the test that I just wrote about. Next time this object will be centre stage.

I've always found that writing about code tends to lead to better code; when you have to explain in detail why things are how they are you can't hide bad design in hand waving. Writing introductory documentation based on complex unit tests seems to bring the system to life in quite a magical way.

Try it!


I obtained similar results when building the demo version* of our smart client application. I found when I ripped out all the guts (eg business logic) of the application and reduced it to its simplest "muscles and skeleton" state, I saw the application much more clearly. It turned into far more than a demonstration app: it became a sort of living documentation that FAR exceeded my expectations. I regularly provide it to new developers so they can quickly get up to speed on the project architecture without being overwhelmed by reams of detailed code.

* Calling this a "hello world" app is probably a misnomer; the complete infrastructure of the app is in place, it just doesn't have any business logic other than the simplest possible demo API calls.

I've had the same experience when writing functionality demos for my server framework. What usually happens is that a client asks for a new feature, X, which we implement for them. We then look at harvesting the implementation out into something that we can reuse for other clients. Part of this harvesting inevitably seems to involve writing an example program that exercises the new feature and doesn't do much else. Documenting the example leaves us with a doc that explains the feature.

The tests as tours thing is a bit different in that rather than having a running skeleton app you have one that can be reliably stepped through - thanks to the tests. This seems to have worked pretty well with the system we're doing at present for one of our clients; the main event is quite complex and being able to trace our way through the processing helps make it appear less so. It gives you a documented path, or two, through the code so that you can venture off and explore on your own, but can also use to quickly get a feel for the entire app.

I'll certainly try to use the technique again.

Leave a comment