Friday, February 19, 2010

Are unit tests the 42 of programming and design?

This is a repost of an entry on my Leo and Pylint blog.

I'm beginning to believe that the answer to this question is 'yes'. (It's certainly not '42' :-)

And I believe I can prove it.

This morning I attempted a rewrite of the complex code that imports Python files into Leo. As I went, it was natural to create unit test as the complexity of the problem became more apparent.

About noon I had to stop for awhile while several (old!) unit tests were failing. During my break, I considered scrapping the approach I was using. So was the effort a failure? Hardly. Amidst the rubble the unit tests stood unscathed.

This isn't an isolated example. Comically, failures create a situation in which unit tests come first the next time around :-)

Now lets consider my recent complaints about packaging. I implied at the end of a recent post that we lacked tools of sufficient power to help us with packaging. Could unit tests be those tools? Yes, they could be.

We need only a slight change in point of view. The typical way of viewing unit tests is to consider them a (permanent!) check of the correctness of a piece of code. This so close to the 42.

Let us instead view unit tests as tools. As tools, they have the following characteristics:

1. Unit tests codify and make explicit desired or expected behavior.

2. Unit tests are a way of "maintaining attention" on a problem. Unit tests don't forget, and they are permanent.

3. Unit tests do whatever we want, and they do it automatically.

What then, is the "effective power" of a unit test? Well, there is no limit to what a unit test can do. A unit test can do whatever we have the wit to require it to do. Unit tests are the master tool for any programmer or designer.

Put it another way, unit tests allow us to focus our attention briefly on a problem, and then, by the nature of a unit test, that attention becomes permanent.

Not convinced? Let's consider the question of packaging.

Suppose I think of unit tests as design tools for packaging issues. What exactly, could not be codified as a unit test? Certainly api's can be codified. Certainly use cases could be codified. Certainly interactions with other packages could be codified.

And so on. As soon as a new concern arises, it becomes possible to create a unit test that addresses that concern! Do you see? Unit test are limited only by our intelligence, commitment and desire.

It seems so clear now. If we wanted a tool of unlimited power, it would have to be limited only by our limitations. But that's exactly what is so about unit tests!


P.S. Seen in this light, design problems are failures to create proper unit tests. Or rather, design problems arise from a failure to see the need for one or more unit tests.


No comments:

Post a Comment