Unit-testing and how little things have changed

12.06.08

Filed Under: work

This is actually a very old article which I wrote back in December 2006 over on my Norwegian blog. In an attempt to make that blog a bit less schizophrenic I thought I would move the English content over here. While looking at some of the old posts I think this one actually is quite good and I actually agree with my earlier statements from 2006 (which is quite unusual for me). Without further nonsense I here by present the old posting entitled:

Why Unit-testing has “nothing” to do with testing

I do not claim to be the master of testdriven developmen, but I have used a testdrvien approach for about two years now. What I have come to realize is that, for me as a programmer, my unit-tests are not most valueable as a way of testing.
Sound stoopid, right? Hold on! Do not stop reading, theres an explaination to this somewhat bizzare statement. What I mean is that my unit-tests help me in a lot of other ways which are actulay more benefical for me as a programmer.

New approach to an old technique

A few years ago I read the first edition of “Code Complete”, which is a great book. I picked up a few tips which helped me improve my speed and accuracy while coding. One of the things was first document what the method should do before the signature, and then “code” the method by writing comments for what you want it to do. By doing this you can more easily see if what you wrote in the method body corresponds to the documentation in the header for the method. You will notice if you need to refactor you method and you can detect logic errors before writing a single line of code. I found this technique to be very useful and it helped me improve the quality of the code and I produced fewer errors in my code.

Unit-testing introduced a more extreme approach which is somewhat simular. Testdriven development evangelists says “You must write you tests first”. This is a new spin to the method mentioned in “Code Complete” by Steve McConnel. By writing the test first you can see if your component meet the requirements, and you will also be able to detect design errors early. In addition you will also write better code for the actual method since it will only meet the requirements in the unit-test.
If you are not writing your tests first, you might as well just skip writing unit-tests. They will pretty much just test that the code you wrote runs, not if your component actualy does what it is supposed to. But, this topic has pretty much been covered by other people so I will leave it at that.
To recap: writing tests first helps me trap design and requirements errors early and improves code quality.

Having the courage to implement change

Refactoring is a word that some people love, and some people think is just a word used by consultants to make money off of their mistakes. Either way, we all know that we somewhere down the line will have to change our code. Nobody writes perfect code that never needs change, that is just a fact.
When the time comes for your component to change, what do you do?
Do you start to sweat and suddenly develop a spiritual conciousness, or do you smile and see this as an opportunity to make the changes you have been dying to do for some time? If you have been a good boy or girl and written your unit-tests you will be in the latter category. This is one of the reasons why I have come to embrace unit-testing. It gives me the confidence to perform required changes. My unit-tests gives me the sound foundation to perform every required change in my application. No more prayers like, “please please let this change be a good one” to the allmight “Runtime God”.

Going fast by never going back

I have seen people estimating more hours because they are doing unit-testing. This is in my opinion dead wrong. This would be equivalent of saying “I will use the IntelliJ debugger, and that will take me 4 hours”. Writing unit-tests should be a natural part of the craft of writing code, therefor it makes no sense to add hours to a budget “because we are gonna unit-test”.
By applying unit-tests in the way I have discussed earlier you will never use mour hours by adding unit-tests. That is because you will detect errors and trap design flaws earlier when writing tests up-front. You might spend an hour our two writing the tests, but you will also spend less time debugging your component. In other word you will go fast, by writing better code that you will not have to back and debug.
Again, this is actualy nothing new. Writing tests first is just a new spin to an old software developement “truth”: you will go faster by trapping errors early.

Summary

Unit-testing has more to do with writing code than testing in a traditional way. I see unit-testing as a tool for:

2008 Update

Having lived and learned a little more over the past two years I think an update is required to what I wrote back when. Testing has another very important purpose which I did not see as clearly then. Which is that tests, if written in a good way, also acts as the best possible documentation about your problem domain and application. Allistar Cockburn mentions in his excellent book Agile Software Development: The Cooperative Game something that was originally written by XXX back in YYY about how documentation of projects is really difficult and the most important things are never put on paper. The most important thing is the “mental model” of those who developed the system. Without a knowledge of that model you will have a hard time taking over an existing project or adding new features to it.

I whole heartedly agree with this point and I think one of the places the model of the developers could be exposed is in the tests. By building a decent test harness you document how you want the system to work and you in turn expose some of the things you had to do when creating the application.
One example is lets say you had a bug which made you have to change your architecture a bit. Following the practice of TDD you would first write a test for this and in the documentation for the test method you would write a small entry about what this test does. Then you would make the architectural change until the test passes. This would expose to people coming in later reading your test code what the reasons for the test and what it solved.

Besides the fact that tests help document the mental model of the developers I think I would not change much in the original article.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Subscribe to comments feed (this is global, not just for this entry)

Categories