Last Tuesday I held a little presentation together with Chris Hedgate about TDD. It was a very small 45-min introduction. Chris did the philosophical part and I myself showed some examples of CPPUNIT and talked about working with TDD in C++. When Chris was holding his presentation he had a picture of a vice. I don't remember what he talked about when he showed the picture but to me it encompassed TDD in a nutshell.
The vice represents what TDD actually is and it helps to clear out some of the initial misconceptions one might have. When I first learned about TDD I did it on my own from books. I had no real life mentor to ask questions so Kent Beck became my mentor through his book. In some way I therefore blame Beck for my initial misconception of TDD as a testing methodology. I'm not saying that Beck today states that TDD is a testing methodology, although it is known to me that he has both said and written this in the past.
I took me quite some time of both using TDD and teaching it to others to learn how it was supposed to be used, it was (and is) a development methodology. I argued this point with Jim Coplien at Öredev. Jim said that if the tests are only there for development I can throw them away once the code is in place, because they aren't tests and therefore fill no purpose in the sense of regression testing. At that point in time I didn't have any good answer to Jims statment. I took the thought with me from the conference and used it to fuel my reasoning. I must say that I now agree with Jim, there is no value in saving tests for regression testing, but there is a value in saving your tests.
Your tests are not actually tests, they are models. Essentially your tests model your assumptions. Every developer makes certain assumptions about the system he is writing. Those assumptions are a vital part of the system; they are not always correct, but none the less vital. What you do when you write tests is you model your assumptions into something concrete that can be read by you and by others that re-visit your code. If these assumptions are not documented and saved they will be forgotten and forever lost. Your code won't make any sense to somebody reading it with different assumptions or even to yourself reading it 20 years later. This is especially important if you make the wrong assumptions, someone searching for a bug in the system might read the tests and see that the bug is actually a flawed assumption. Such a flawed assumption would probably take a very long time to find if it wasn't documented properly in a test. These assumptions are your code vice. Essentially you build a vice with your assumptions and use it to fix your code’s assumed functionality in place. This means that you can guarantee that the system does what you assume it does. It also gives you the stability to change the code structure (refactor) without changing the way you assume it works. So you are not actually guaranteeing that your code works in any way, that is still QA's job, your just guaranteeing that your code works in the way you assume it should work.
I have known this for quite a while now; people that have been to my TDD talks or discussed TDD with me surely have heard the phrase “TDD is NOT testing”, I can’t stress that enough. By saying this I hope I can save people from making the same mistakes as I did in the beginning. Without the vice however I would probably not be able to articulate it this well. Thanks for the vice Chris.