So what do I think of TDD after I've been using it for over a year? (And on two projects, since I abandoned that prototype to work on Schizoid.)
Frankly, I'm disappointed. I was hoping for a bigger, more obvious win.
The number of "false positives" - tests that break because my assumptions changed - greatly outnumbers the number of real bugs really caught.
Also, they say it improves your code style, design, and architecture Frankly, my code architecture is worse, as I frequently expose things I wouldn't have exposed so I can get them under test more easily - and other abuses.
And we still end up introducing lots of bugs into the code. Partly because we're not covering everything (not only are we not covering cosmetic features, "is this sprite/menu item/whatever in the right place?", we're not covering experiments, "Will it be more fun this way?" even if those experiments end up sticking) and partly because you just can't cover all the cases of all the functions, and partly because the tests don't catch multithread problems. The number of bugs still introduced is an order of magnitude higher than the number of times a unit test correctly catches a real mistake. (Although a more optimistic way of looking at it is: unit tests are catching almost 10% of our bugs!)
Not a silver bullet.
All that said, I'M NOT GOING BACK.
Although the code quality may be worse, my understanding of the code is very high. Code I wrote months and months ago, code that I've totally forgotten how it was supposed to work...I write tests, and the tests fail, and I have to dig in to understand why the tests fail, and then I have these a-ha moments - that's what the code does, that's what it's supposed to do, hmm, okay. Ditto with working on the other coders' code. The result here being hard to measure - I understand the code better, so I'm not writing bugs in the first place!
I suppose someone might say, "Why not have some discipline and make sure you understand code you're changing? You don't need TDD for that." Well, I almost always *think* I understand the code when I change it. (Unless I'm in one of those, "Eh, let's just see if this works" moods...I suppose I could use more discipline there.) But do I really? That's where the TDD really helps.
This is huge, and is a benefit of TDD I don't hear mentioned that often. Spread the word.