I can talk only from my experience. For me TDD brought several things I didn't have before in my development style habits toolbox. Although, it is worth to say again that TDD is not solution to everything. I always try to separate exploration and production ready implementation. TDD in exploration phase is absolutely not needed and even is slowing down. On the other side for production ready code it brings several benefits which on short and long run are very valuable for the mental health of developers and karma of the project.
- TDD makes me think before I implement, which is usually very good practice which prevents lot of shoot and forget solutions
- It makes me think in small portions of problem, forcing me to break apart solution to small pieces that fit together.
- It makes me write very decoupled code because whenever I have to stub/mock/fake something which doesn't fit into the problem I naturally throw one "WTF, why should I do this if I don't have to be coupled with it". And it makes me realize connections between thingthings better.
- It gives me set of easily executable checks for my code, so I don't have to go through painful "var_dump", "p", "pp", "echo" style of debugging of code. It just reports what is wrong, when is wrong. And if I don't have a check for it yet, it is just matter of adding simple test to check ifit over and over again.
- It makes me certain that my code works if all tests pass before we deploy and execute all the test. Then instead of eating my nails I go eating a cake and drinking coffe and enjoying my afternoons.
- High level tests are very nice in the cases you have to refactor something. If my module has to provide some functionality to outside world and I have developed functional/integration/cucumber tests to prove it's working correctly I will be very brave to refactor the hell out of that code. Several times I was faced with the code that didn't have tests and need to refactor it. In that case there were two ways to go in practice. 1) drop the code 2) skip the changes and leave it as it is.
There is one thing that TDD doesn't fix. If you don't know how to build the thing you are building, then TDD will not produce solution for you. You need to have rough "design" or overview of the problem and solution. TDD will make you just implement it in more elegant and maintainable way with the code of higher quality.
At last, I prefer thinking in BDD terms which lean on TDD practices. BDD makes me to implement solution using vocabulary of the domain and to make software fit the problem better.