The Driven Premise
Here’s an illustration of the most basic principle of TDD, what I call the "Driven Premise": there once was a queen who had a thousand consorts, each more brave and handsome than the next. But only if you lined them up that way.
The driven premise says that tests & testability are first-class participants in design.
When they are, then producing rock-solid code that does exactly what the author wanted it to do is easy. The result is a kind of soaring confidence, an ability to add new function to an existing system very nearly at the speed of thought.
Further, those tests serve as a source of confidence & authority not just for the original author, but for all comers. And if you’re a hard-TDD’er, which I am, you’ll go even further: making those tests make yours design better even w/o the tests.
Line Them Up
So working in this way, following the driven premise with vigor, produces great results. But. Only if you line them up that way. Tests written for code where tests & testability are not first-class design citizens just don’t work as well. The expense of creating those tests starts to mount as the tests gain complexity, which they inevitably do because we didn’t line things up. The more expensive the test, the less likely I am to write it or run it, the less likely you are to read it or even parse it.
TDD works because we line the code up in a highly testable way. If doesn’t work when we don’t line it up that way.
So if you’re plunging in to TDD, the first thing you have to do is learn to change your design to account for tests & testability. What you are doing is lining up your system so that each element is more brave and handsome than the last.