This article misunderstands TDD completely. In TDD, the tests are your specifications. Therefore, any code that passes the tests is formally correct - even though it should always be minimal (YAGNI).
In fact, TDD is not simply "tests first". It is: write ONE test, make it pass with the MINIMUM amount of code, refactor, loop.
Usually this makes people go for very simple solutions without thinking properly what are the right data structures and algorithms for the problem at hand.
I rather write proper designed code and write the tests afterwards, before delivering the code.
True, however the solution is ok since passing the test is the only quality you need.
If not, write a new test, make it pass. The naive implementation can be substituted with a different one easily since the tests guarantee correctness.
Generally though, since the "third leg" of TDD is refactoring, this ensures that the proper structures are going to be used in place as soon as they are actually needed.
No one is disputing that the code is formally correct. The problem is that the code is generally focused on those specific tests and those tests alone. Meaning the code hasn't been designed or architected with a broader context in mind.
Hence over time the codebase becomes this huge tangled mess of "formally correct solutions".
In fact, TDD is not simply "tests first". It is: write ONE test, make it pass with the MINIMUM amount of code, refactor, loop.