In short, no. TDD is neither necessary nor sufficient for testability. You can write testable code without doing TDD, and doing TDD doesn't guarantee testable (that is, easy to test) code. Doing TDD without a clear understanding of how to write testable code results in unnecessary testing pain and doesn't yield the expected benefits.
TDD does help to produce more testable code by creating warning signs (that is, testing pain) when there are testability problems with the code. But TDD is a means to an end and is not an end in itself. Testability is the end. TDD helps to achieve the end, but it doesn't guarantee it.
Nat Pryce summed the relationship between TDD and testability perfectly in a tweet today about TDD and design:
TDD does not drive towards a good design, it drives away from a bad design. If you know what good design is, the result is a better design.In the same way, TDD drives away from a lack of testability by creating pain for testability problems. If you approach TDD with an understanding of how to write testable code, your testing path will be much smoother with more effective results. So how does one write testable code? That's the subject of the next post in which I will give testability guidelines and discuss how failure to follow the guidelines creates testing pain and friction.