Oh no… not again. It’s almost dangerous to touch this subject as a professional. Let’s see if I turn into stone.
People still talk about this matter, although from a very different angle than DHH back then. Today I was at a talk of Sandro Mancuso in Zurich called “Does TDD lead to good design?”. Sandro approached the question by explaining the difference between the two major TDD schools “Classicist” (Chicago) and “Mockist” (London). Classicists are focussed on having the fastest possible cycle always focussing on the next increment reachable from a class. The system evolves organically around the application state. Mockists on the other hand do a big portion of designing first, because they focus on the behaviour (or the outer interface) of the system. Both schools have different advantages and disadvantages. Sandro then explained for both schools where design can happen and how. This clearly lead to the conclusion that design isn’t done with TDD. Design is done by the programmer(s) somewhere in the cycle steps with tools like DRY, SOLID, etc., but not as a part of the TDD tool.
So design quality depends on the expertise of the programmer and the ability to use the right tool for the right job (e. g. hammer for nails). My theory is now that unexperienced software developers can build a system of poor architecture because they use TDD (especially with the classicist approach). The endorphin shot whenever a test becomes green lets them repeat the cycle without conscientiously stepping back and thinking about the bigger picture (and every screw suddenly looks like a nail). They are in the flow and suddenly they have service objects everywhere.
I’d even go a step further: having tests at all can lead to bad design. That is because tests are part of your software architecture. We all struggle to handle more tiers of complexity. Isn’t it already demanding enough to let inexperienced programmes juggle requirements and software architecture in their brain? No, apparently not: experienced professionals come now and tell the juniors to add automated tests and TDD to their brain stack while assuming that this will have no influence on the quality of the software design. That’s presumptuous!
I agree, that juniors need to learn about automated tests and TDD. In my eyes, it’s the only way to professionally develop software. But I think we should never forget to teach how to design the code which does all the work in the end. Let’s build something ugly and then discuss, why it’s ugly — just leaving away the testing overhead for once. I myself needed to go a long and hacky way of poorly designed software until I learned to value automated tests and TDD. Why should it be different for other people?