Cedric Beust has written a well considered counter to TDD extremism. He is right in that TDD can seem compelling when writing simple class structures, but that it can become a hindrance when coding more complex cases. The argument to that, of course, is that TDD will help refine your API and integration points, but I think the point really is that it’s perfectly possible to have an elegant interface without TDD. As Cedric says, TDD should be considered simply one of an array of tools.
Cedric’s “rules of thumb” are good:
- "Tests first" or "tests last" is unimportant as long as there are tests.
- Try to think about testing as early as possible in your development process.
- Don't let one liners contradict your experience. For example, don't listen to people who tell you to write "the simplest possible thing that could possibly work", also known as YAGNI. If your experience tells you you're going to need this extra class in the future even if it's not needed right now, follow your judgment and add it now.
- Keep in mind that functional tests are the only tests that really matter to your users. Unit tests are just a convenience for you, the developer. A luxury. If you have time to write unit tests, great: they will save you time down the road when you need to track bugs. But if you don't, make sure that your functional tests cover what your users expect from your product.
- Don't feel bad if you are not doing Test-Driven Development. There are a lot of factors that make this practice a bad fit for a lot of projects and developer personalities (aspects which are very often never mentioned by TDD extremists).
I’m not at all against TDD, and indeed, I use RSpec with Rails consistently before coding implementations, but the point is let’s not get fanatical about this. It’s not a cure-all.