This is a true story, but for the sake of protecting some people, all the names and other details have been skipped or changed.
It starts on some Thursday with some new guy asking me “how much TDD is slowing down the programmer”? I don’t have to think twice, my instant answer is: “programming with TDD is faster than programming without”. The guy doesn’t believe me, some other SQL guy joins, doubting as well. I see no point in explaining it to people who don’t touch OO code. They won’t believe anyway, as it is counter-intuitive, if you have not experienced it yourself. But then, life has a funny way of giving you proofs right when you need them.
Next day I’m being asked to help put out some fire. There was a project running, two junior programmers were writing a small application, one of them doing the frontend, one doing the backend. No help from any senior or architect along the way. No code reviews, no pair programming, no nothing. Things, as expected, went terribly wrong, deadlines are weeks behind, the client is furious, and the software is not doing the stuff it’s supposed to. Oh, and the backend programmer is already on the way to another continent. Some guys tried to debug the problem, but after six hours of getting nowhere, they gave up. A classic FUBAR example.
All right, I say. I know the frontend programmer, he’s a good guy, I like doing pair programming with him. He doesn’t know much about the other guy’s code, but he knows the business domain. I’ll help as much as I can. So we checks out the code, we setup the IDE and look inside the backend.
And the abbys looks back into us.
We stare into the Eye of Terror. A complete chaos, infested with chaos spawns. A terrible place to look at. Things can break your mind in here. It’s twisted, it’s evil and it’s tragic. Pretty much every principle of OOP is violated. I could give it as an example of things that should not be, except I’d hurt the audience. There are no tests, there is a lot of faulty inheritance, with abstracts knowing about the children, there are hundreds of ‘ifs’, ‘elses’ and even some ‘case-switches’. Hell, there are even misleading comments! There is a ‘new’ keyword in every constructor, no IoC, no interfaces, no nothing. No sane mind can leave this place intact.
We take a deep breath, and we try to find out where the problem might exactly be, but as we dig into this Big Ball of Mud, we realize that the problem we are facing is just a tip of an iceberg. The software does not guarantee anything, and as far as we can tell, there is a shitload of bugs all around the place. The main algorithm is so twisted that it takes us hours to understand it, while the purpose of the whole thing is dead simple.
Ok, so we’ve nailed down the possible problem. I’m suggesting writing a test to repeat the bug client had reported, and then fixing it, but the problem is, that the code, the way it is now, can only be tested end-to-end, so we have a lot of setup to do. My fellow programmer’s mind is already burned out, he asks me to call it a day. He also says, that he’d rather rewrite the whole module instead of digging any further, because if he has to look again into this mess, he will never be normal again.
All right. I’m a bit more resistant, but I’ve not exhausted myself with debugging it before, and I’ve seen things, you people “wouldn’t want to believe”.
So we set up an emergency pair programming session on Saturday. Now it’s late Friday, and I’m heading for two parties I’ve planned to visit that night.
Saturday, 1pm. Sun is shining, weather is beautiful, girls are dancing in the middle of the town. I’m heading for the meeting. I’m expecting some heavy code crunching today, killing chaos monsters and stuff, but when I get there, the other guy says he couldn’t sleep. Knowing the main purpose and the twisted algorithms, he has been working till 4am, writing everything from the scratch. Maybe not everything, but the main stuff anyway. He’s been doing TDD, and though he has lost some benefits of discovering optimal interfaces/architecture, because he’s been writing interface-first, then Red-Green-Refactor style, he got it quite well.
The code is doing about 80% of what it’s supposed to do, test coverage is sky-high (except for DTOs), there are some minor issues with ubiquitous language and so on, but for a single person junior programming this is a pretty sweet piece of code.
“Great job” I say, amazed by his late-night work. What should we do now?
So I help him write an acceptance test. We make it run all clean and green. We talk about the decisions he has made, I’m giving him advices and suggestions, but I can clearly see, that the guy has defeated an ugly dragon last night. He took his TDD spear, stormed the whole army of enemy warriors, killed them all and now he’s on his way for the princess. Well done man, If I had a medal with me, I’d give it to you right now. You deserve a big thanks from all of the humanity for putting the beast down.
And he’s saying, that if he ever had doubts about TDD, he doesn’t have any now. He has really learned something that night, he gained a lot of experience points, and he has leveled up at least two times.
There is still some work to be done, but it’s easy from now on. The client is safe and sound.
And now for the conclusion: it took him LESS time to rewrite the whole module, using TDD, that it took, to find one bug in the old application.
How’s that for an answer?
PS: pictures are from www.studiocombo.pl