TDD is a great utility, which can assist in keeping a high quality level in your code project. However, regardless of the recommendation of the methodology, I also want to highlight some of the limits of TDD. Some of these limitations are based on my own personal experience and should be evaluated as so.
Writing the testing code before the implementation theoretically sounds like a great idea. However, in reality we do not always know what type of implementation we are going to create. Perhaps I will separate the functionality into five different classes during my initial implementation. Should I then also go back and separate my test cases into five test classes? To be honest, writing test cases will in many scenarios end up taking too much time for it to be realistically feasible.
….But should we then never use TDD? No. TDD has its time and place. However, it requires a definition of what to except from the code implementation. I therefore utilize TDD when working with external interfaces in an end-to-end (E2E) test setup. Since the interface already has an explicitly define expected functionality for each API call, it will be simple and reliable to create a test case which matches this behaviour. Additionally, since it is used as and E2E test case it is not limited to one specific class.
From my experience this works great for both creating the intended functionality, maintain the quality of code, and the speed of implementation.