I’ve found the propaganda, hyperbole and stints of doing TDD alluring but I never really found it sticks, much like an intensive exercise regime. My sentiment is that it’s a methodology more concerned with code quality than user value or time constraints.
I have however found a sustainable flow that gives me a lot of the upside of writing tests with a reduction in the downside of writing upfront tests & code for features that turned out to be misguided and ultimately scrapped. I believe in accepting change rather than fighting it (as is tempting to do once you’ve got “skin in the game” under TDD) as you can’t expect a user story to be written watertight first time.
I’ve called this process “scouting” which involves taking on a new user story, writing what’s essentially prototype quality code, getting stakeholder feedback on an early demonstrable flow, iterating until the proposal is validated. Once there’s a loose sign off of what’s been presented, I’ll drop down to writing unit and integration tests in anger as there’s a clear(er) idea of what’s needed to be shipped. This phase will also include bringing the prototype quality code to production quality (ironing out ignored edge cases, accessibility, security etc).
I tend to iterate and evolve “prototype quality code” even though I’ve heard the arguments of treating it as dirty and disposable a trillion times before. Perhaps this is because I’ve had enough best practices instilled in me that I write a half reasonable code first time but more plausibly, it’s because I’m human and would prefer to get value to customers sooner than ship perfect code weeks or months overdue.