TDD, or rather the effort behind TDD, failed because its proponents couldn't help but preach it as a cornucopia of solutions with the insistence that it's appropriate for every circumstance. When you are familiar with the domain of a problem, TDD makes a lot of sense. For the project I'm working on now where I'm effectively learning at just about every step of the way, and said project is intended for very few users, it's highly questionable if I could have benefited from TDD. Even when I'm not doing something unusual, TDD doesn't always make sense.

Any research that currently exists around TDD is of poor quality and proves little, but TDD fanatics (not sure how many of them exist anymore though) speak like there's objective evidence in their favor. And some call this sort of thing "science"?

By the way, when I mentioned science, I was specifically referring to the concept of "computer science", of which there has been very little actual use of the scientific method in our lifetimes. Computer science is of course a legitimate area of study; if our heads are still so in the clouds that we are still calling it a "science" then it's no surprise that we're continually losing touch with the very technologies we create.

TDD also shot itself in the foot with this (IMO toxic) insistence that the tests are the documentation, which is a nice principle to keep in mind, but I've never seen it come close to replacing actual documentation. A simple comment block describing the why of a function is always better than scrolling through tests and reconciling inconsistencies with the mocks that were used. And yeah, I know that TDDing isn't really about "mocking", but let's face it [...].

Perhaps the worst thing of all is that TDD is founded on a somewhat dishonest implicit premise, which is that if you aren't TDD'ing then one must be either not writing enough tests or are writing inferior code because one is writing tests after development. TDD fanatics, in particular those freshly inducted into the cult, often think it's either TDD or nothing, and if you're not TDD'ing one particular part of an app then you're not following "standards". Maybe TDD is fine as a form of guard rails when you're a junior developer, but by the time you're a high mid-level and in touch with reality then you're going to intuit whether a unit of work will actually benefit from TDD.

TDD isn't bad at all in terms of its mechanics. It's a great idea, and I've used it many times. In fact I even TDD'd an entire web app that handled payment processing from start to finish. The part about TDD that "failed" was this belief that it is actually a generalized solution that needs to be applied everywhere, which lead to it both being misapplied as well as dismissed when it becomes apparent that those promises of better and easier code/process/readability often don't magically manifest.

This is really the story behind just about every failed idea related to our field, not just TDD. SPAs were supposed to make pages snappier because it meant server responses to different user actions would require fewer bytes and no page refreshes. Instead of viewing SPAs as a tool with a purpose, people had to treat SPAs as the end-all-be-all of frontend development and a way to do everything, and now the world is stuck with many SPAs that are likely worse than if they were done as regular webpages.