Pages

05 December 2005

Test-driven development : a practical guide - 2 years later

Oh well, this book (Test-driven development: a practical guide by Dave Astels) is not so new. Yet, I believe that not so many developers (including myself) have really acknowledged the messages it conveys.

Having read it 2 days ago, I take the opportunity to sum up some of the ideas that are exposed in this mind-agitating book.

  1. Tests are only a by-product of test-driven development (TDD). The primary aim is to develop good software confidently (see my previous post on Behaviour-driven development)
  2. Unit testing a java gui is possible
  3. Developing a system with TDD leads to a well-crafted system if we refer to the metrics ran at the end of the sample project
  4. Why would you ever need a debugger?
Now, more on my personal thought about this book and its messages:

Be humble

Dave insists (heavily,...) on that: do a tiny little bit at the time, and of course, as a real XPer, do the simple thing that could possibly work. I feel this is really not so easy. When I develop code, I am very, very, very tempted to write more than I have tests for. What in the hell could be wrong with that simple iteration on my collection to get the object with the right name?

The trouble is I have too often seen those kind of stupid mistakes:

int i = 0;
while (iterator.hasNext()){

t_object = (Entity) iterator.next();
if (t_object.getName().equals(p_name))
break;
}
return i;

OR

if (p_param >= 10);

doThat(p_param);

Yeah, it's so easy to write code, but it's so easy to write wrong code, even if you're more brillant than Marilyn vos Savant. By the way, did you spotted the errors? The first piece of code returned a counter that wasn't incremented,... and the second one had a supplementary semi-column after the decision in the if (I did this one at least 3 times in my coding career, and I am sick of it since my brain can be real slow on just spotting that parasite character).

So, be humble, don't trust your "best developer of the month" diploma, assume that every little bit has to be correct.

Use one set-up per fixture

This is a discovery for me. I always tended to think: "there should be at least a test class per production class". Yes, sure, but there can be so many more: the trick is to really use the setUp methods for factoring the fixtures for the assertions you want to make. And If you want to create another fixture, create an another class. This way you will end up with specific classes for specific contexts and with test methods that contain merely the minimum of what's needed.

There is no such thing as a free good design

From the beginning of his example, Dave shows us that he has a good idea of what should be a good design:
  • proper use of interfaces
  • clear separation between business code, UI code and persistence code
  • ultra-thin UI (this allows an easier testing of the UI)
I think that TDD can reinforce a good design (hence the proper metrics at the end of the experiment) but I am not sure that TDD leads you automatically to a good design, even if you refactor a lot. This is why XP mandates the use of exploratory design. At some point you may have to experiment in order to find the right ideas.

Using the debugger is a "smell"

I read this months ago, and I often remember this when using the debugger. Using the debugger makes me think that I don't really know the behaviour of the system I am using. Then, like St-Thomas, I have to take a look at it.

Moreover the use of the debugger tends to encourage a code-and-fix attitude: I code, then I will ask the debugger for what is wrong. And this gets worse with tools such as Eclipse where you can modify code on the fly and re-execute it in the same debugging session.

So when you want to ascertain the behaviour of your system, it is much better to make an hypothesis and write a test case to make sure you're right.

Eventually, there may be a 5th XP value: Disciplin,...