In order to write the tests you need to have a clear idea of what you want the project to do. We know that clients, above all in the initial phase of a project, never know exactly what they want and are apt to change their minds rather frequently! It's important to remember that the problem here is not the testing itself; rather, it is the testing that shines light upon the real problems. The act of writing the tests itself makes it impossible to ignore problems and makes it necessary to confront and resolve them.

All developers need practice to get used to working with the idea that code has to pass through tests before further development can take place. In part, this depends on the skills and experience of the developer, but even a very good developer who isn't particularly confident with TDD will find getting used to this way of working and thinking extremely uncomfortable.

Writing good tests isn't easy. It requires testing something that does not yet exist, without falling into the trap of pre-engineering the application. There is also the lurking threat of over-engineering to be avoided: entering too deeply into the details of an element of functionality increases the risk of over-generalizing and implementing behaviour and tests that have not been requested and are not really necessary.

Then you get into the wonderful world of doubling up! In addition to the "visible" application, it's also necessary to maintain the test suit, which is itself made up of code! If the tests aren't treated with the same (or greater) care than the application code itself, then we risk putting our trust in a weak instrument.

Twice the amount of code. The ratio of test code to code is generally around 2:1. And if a test suite ends up having twice as much code in it as the app it's designed to test does, where is the greatest risk of an explosion of chaos occurring? Be very, very careful!

Twice the budget. We have to write 200% extra code, above all during the initial start-up phase. This takes time and, obviously, money!