lunedì 14 febbraio 2011

Why I like TDD. And I don't use it.

The first time I really understood the meaning of Test First Development (TFD) was like some kind or revelation.
I was already using automated testing, but most of the times the tests were written after the code. The few times I tried to write tests first, well, the result was not so brilliant. A lot of wasted time for some bad testing code. But still I wanted to to understand all the hype around TFD.
So, I continued to try it in some form, and continued to read a lot of technical books and articles about testing.

And I still remember that I was on the train back form work, reading some technical book (I don't remeber exactly, but it was not a book about testing, maybe about Tapestry or Hibernate or some other framework), when I read something that helped me to understand it. Like often happens in those 'bang' moments, after you don't remember exactly what happened (and I don't remember exaclty what I've read), you just understand that you know something more. And I mean, you really 'know', fully understand something.

Anyway, back to the topic...
What I understood was that with test last you are testing what your code does: that the code does what you want it to do correctly. With test first, you are testing that the code that you are going to write does exactly what it's required to do. It's a small but significant difference.
With test last development, you are testing only that your code behaves like you want, but not like the specification wants. And since you already have written the code, sometimes you don't notice that what you code does is NOT exactly what it should do. You know, after you write something it's like a newborn child. And every baby is good to his mam.

But, again, I don't want to explain in details what TFD is. I'm sure that you will find someone on Google (or Bing if you prefer) better than me in explaining that.
I just wanted to say that in that moment I understood the benefits of writing test first. And for some time I tried to do it.
But then I realized that most of the time this wonderful technique cannot be used.

And the reason is simple.
WIth TFD you write tests first to test that your code does what it should do according to the specifications.
But most of the time you don't know it exactly before writing the code, as specifications are just some dim lights far away. The customer doesn't know exactly what he wants, and if he knows, he will surely change his mind soon after the first test.
It's always happened in the projects I've worked, even in the most structured one. And I've worked in a lot of projects in the last years, with teams ranging from 1 (only me) to 30 people.

You end up with some sort of 'waste time to understand specs and write test-waste time to code and understand that maybe you didn't understand the specs so well-change the test and the code-hope that who has to decide (maybe you) really decided this time-change it again-start form the beginning' cycle.

It's not bad, after all everyone says that you have to write and then refactor your code. Good, I like to refactor. But if you refactor just because you didn't know exactly what to do in the first place, and you have to refactor the tests too for that reason, then writing the tests is a waste of time.
You end up to some point whan you have not enough time to refacor the code AND the tests. So you start leaving the tests behind. Maybe you comment them, or just remove some assertions. Or simply delete some of them because the code under test is not there anymore. Anyway, at the end they are not perfectly in sync with the code they should test.

Am I saying that tests are just a waste of time ? Absolutely not. I write as much tests as I can. But not in the early stage of the development.

So, what is my current process these days ?
First I write the code, without any test, according to what was my understanding of the specs. Then, when I have to change it or rewrite it (and I always have to do it in early stages), i don't have to refactor some old and outdated tests. I don't write any test, unless I have to refactor some piece of code that seems quite stable. Are there any bugs ? Probably, but I don't care too much. When some functionality is quite stable and confirmed then I write the most complete test suite that is worth for that code. And not more.

So, just to end up, what I'm saying is that TFD, or even too extensive TLD, for my experience are not to be used in the first stages of a project, when the main architecture and specifications are not clear. You waste a lot of time in writing test code to test functionality that will not see the production stage.

I know this is not probably teh best way to go, but often we have limited resources, and like Bruce Springsteen said:

'Between our dreams and actions lies this world'

It's been a long time...

...since my last post.
Whew...more than one year. A busy year.
I know that you don't care about what I've done in the last year, and I won't tell you.

So, why am I back here on the blog ?
Well, when I decided to write a blog was just to keep some sort of technical notebook. Sometimes I had some particular problem for which I could not find a good solution on Internet, or simply I just wanted to take note on how to do something. Like in a schetchbook. But then, most of the time I simply forgot to write on the blog, even about some really interesting stuff.

So, the question again, why am I back here after all this time ?

In the last years I've worked on a lot of diferent projects, often with some really good people. Now, in the last few months, I've been mainly working from home, and I will for at least some more months.
And I miss all those coffee machine talks with those great developers, all those wonderful technology insight that came out in front of a drink or a beer at the Sports Bar. So, I'm writing here some of the things that I would say there. Not only a virtual notebook, but also a virtual coffee machine and a virtual Sports Bar. Almost the same as the real one.

Except for the beer, of course.