One of the biggest reasons I see for TDD not being used enough is that it makes things harder. The typical complaints are:
- "I have to setup/mock too much"
- "I want to test my complicated internals without exposing them"
- "I'm writing a web-app, it's hard to get the interactions right"
All of these should be alarm bells in your head. The design needs a rethink. These alarm bells are one of the benefits of TDD - if it's getting tough then the design probably needs a rethink.
Too much setup/mocking
This likely indicates that your classes are too coupled. Consider the following:
- Is there any functionality that is in the wrong place? Should it be moved to a different/new class?
- Should you create a simple class with little logic that provides the glue for your application?
- Have you considered inversion of control?
Testing Complicated Internals
Sometimes you start with something simple and then it gets more complicated. As it gets more complicated the internals get more complex and you start wanting to test the internals to make sure your state is correct. Don't.
Instead, consider whether those internals could be extracted out in to a new class which has the sole purpose of implementing the complex logic you were trying to hide away.
This makes testing easier, improves re-usability and leads to code that is easier to understand.
Testing web-apps can require a different set of tools. Often, you want to be using some sort of browser based testing as well as your normal testing. Most of your browser based testing should be simple (little logic) and be something of a formality.
If you have all your business logic tidied away nicely in to your models then your views and their controllers should be simple. Your tests for these should then be simple.
You should be able to directly call methods on your controllers to test any logic present in them. If you can't, then it is likely there is logic in the wrong place or you are storing too much state.