Jimmy Bogard has a post up about how to write effective UI tests. You should read it, as it’s a really good post.
Though it isn’t really part of his point, I want to ‘hijack’ something that he says for my own purposes:
“For about 3 years, I wrote absolutely horrible UI tests. These tests worked great for a while, but like most people that tried their hands at UI tests, found them to be utterly brittle and unmaintainable in the face of change.
And, like most people, I would mark these tests explicit or ignored, until I ditched most or all of them. I’ve heard this story over and over again, from folks that wrote lots and lots of UI tests, only to see their investment go to waste as the time and effort to maintain these often-breaking tests far outweighs any benefit gained from full, end-to-end UI tests.”
Jimmy is talking about UI tests, obviously, but I think what he says applies to TDD in general.
As any reader of my blog knows, I think TDD sucks. To be clear, I think that developing without TDD sucks also, so there’s a cost/benefit analysis that needs to be done in any event, but one of the things that has been common in almost all ‘real-world’ experience reports about using TDD is that it sucks, for a (usually) long period of time, and then the practitioners figure out ways to make it suck less.
I think that there is something specific about TDD which causes this, and is yet another reason to avoid it. And I think it also applies to UI testing that is improperly focused.
Suppose you are building a framework, especially a framework where you don’t have any realistic idea of how that framework is going to be used. In this case, use TDD. Test happy paths, test odd paths, test bizarre paths.
For everyone else, where you are building an application, don’t use TDD. Test at the level of the application, which means using Context/Specification style testing. What does your app actually do? Prevent odd and bizarre and stupid paths at the application level, and then test what happens on the happy path.
Do not try to force TDD on teams that aren’t experienced with it, because what will happen is that the team will produce horrible and brittle tests that are unmaintainable. If you’ve ever been in a situation where this sort of thing happens, it’s totally discouraging. It spreads the idea that there’s something wrong with testing.
Don’t use TDD. Move beyond it. Please.