In my last post Beyond Static Typing, I dropped a bomb shell at the end and invented the ideology Design by Runs at Compile Time. But I didn't really dive into my proceived issues with TDD.
There is a laundry list af benefits. But that list doesn't even mention that it helps in making testable code. Did you know that if you want to write tests which validates logic without dependency you build a design different than if you just integrate directly?
Now this does not sound like a bad thing. Especially when coupled all those documenting tests which allow you to understand the desired behavior and throw out the code, rewriting it based on the tests alone. Not that anyone expects that to happen or be useful.
To remove dependency can require layers of abstraction, also a good thing. Abstraction can lead to boilerplate and worse obfuscation. TDD is about design, but it doesn't force or check for good design.
Consider the ideal, you'd define a scenario, given some situation and you are in a state when a request comes in then you would specify the desired outcome. The compiler would figure out how to get those elements to line up and build your program. This is the logic paradigm or machine learning. As programmers we don't get to write code at this level because we write the code to let others work at this level.
This means we have to balance the abstractions we use to expand code reuse (for bug fix and prevention) while maintaining enough info about what the computer is doing in order to find and fix bugs.
This is where TDD puts test readability above code readability incorrectly. Unit tests will help confidence that a refractor won't break behavior but it won't tell you where a bug is when you need to track one down, reading the code, possibly with the help of debuggers, will.
I'm not going claim anyone will be able to write universally readable code across all domains for every situation. But obfuscation of process to achieve testability is detrimental to code verification. I'm reading your code to find those edge cases and inconsistencies you missed, make it easy on me and your future self.
If you want to have well designed code, it falls on you to determine your audience, your domain, and so many more factors about the specific feature you're implementing amongst the existing code base.