First and foremost, I does not treat anything as gospel. TDD, like everythingthing else, might not make sense in all scenarios.<p>I often use TDD for microservices. It forces me to define REST service interface from the perspective of consumers, and only then jump into implementing it. So I write tests that call the service for various use cases, and asserts for returned status code, pay load, and any invariances. All tests fail initially.<p>It is indeed cumbersome, requires disipline, but it becomes easier with practice. I find, it particularly useful for for microservices. Earlier I would implement, then test, and while doing both will keep figuring a better API and keep changing. With TDD, I upfront get the clarity what functionality I want to implement, so counterintuitively TDD makes me faster.<p>I use it mostly wherever interfaces are involved. For example, if my service is using a DB, unless the use cases are too simple, I write tests for that API.<p>Parts that does not have (external) interface, and I want it to be fluid/evolve, I write tests only after implementing. But service level (TDD) tests provide some safety net.<p>I can see this approach can be extended at all levels, but I am not sure about costs vs. benefits tradeoffs. I think if I do TDD only for macro (process/service/subsystem interfaces kind of things) and some leaf library type modules, tradeoffs are favourable. And if you have TDD for those, the returns of doing it for rest diminish.<p>Disclaimer: I haven't done detailed study, I am telling my experience, so only one data point.