It's all about tradeoffs. I've done a few decades of non-TDD with a middle period of ~5 years of zealot-level commitment to TDD, and as a rule of thumb, the cost is usually not worth the benefit.
Some hidden/unexpected side effects of TDD include the often extremely high cost of maintaining the tests once you get past the simple cases, the subtle incentive to not think too holistically about certain things, and the progression as a developer in which you naturally improve and stop writing the types of bugs that basic tests are good at catching but which you continue to write anyway (a real benefit, sure, but one that further devalues the tests). The cost of creating a test that would have caught the really "interesting" bugs is often exorbitant, both up front and to maintain.
The closest thing I've encountered to a reliable exception is that having e.g. a comprehensive suite of regression tests is really great when you are doing a total rewrite of a library or critical routine. But even that doesn't necessarily mean that the cost of creating and maintaining that test suite was worth it, and so far every time I've encountered this situation, it's always been relatively easy to amass a huge collection of real world test data, which not only exercises the code to be replaced but also provides you a high degree of confidence that the rewrite is correct.
Some hidden/unexpected side effects of TDD include the often extremely high cost of maintaining the tests once you get past the simple cases, the subtle incentive to not think too holistically about certain things, and the progression as a developer in which you naturally improve and stop writing the types of bugs that basic tests are good at catching but which you continue to write anyway (a real benefit, sure, but one that further devalues the tests). The cost of creating a test that would have caught the really "interesting" bugs is often exorbitant, both up front and to maintain.
The closest thing I've encountered to a reliable exception is that having e.g. a comprehensive suite of regression tests is really great when you are doing a total rewrite of a library or critical routine. But even that doesn't necessarily mean that the cost of creating and maintaining that test suite was worth it, and so far every time I've encountered this situation, it's always been relatively easy to amass a huge collection of real world test data, which not only exercises the code to be replaced but also provides you a high degree of confidence that the rewrite is correct.