Aug 21, 2009 16:13
Don't get me wrong, I love the big fluffy warm feeling I get from having a whole set of tests telling me the code works and it's safe to ship. I will even (in certain places) use this as an argument as to why you need to write tests - mostly when talking to people who just don't see the value in test code (also known as stupid people). It's not, however the reason why I so enthusiastically adopted TDD (Test Driven Development, or Test Driven Design - you decide which I prefer).
I've had conversation with skilled developers who confidently assert that they'd love to write good test code, but they don't have time to. The deadline looms, they have working code, they just don't have time to write the tests before they ship it. Then the next set of work needs doing, so they never write the tests for the last set, and strangely, the next piece of work also goes without tests. Then the defect rate starts to climb. The code complexity is on a steady increase and suddenly (often not very far into the project) even relatively simple changes become painful. Every possible implication of each keystroke has to be considered - often exhaustively. This sort of behaviour is often associated with people who make their code overly complicated, and that's often the reason given for why they start to go so much slower, but it's just not the case. They slow down so much because they spend so much time working out what might go wrong.
Compare this with the chap who's written his tests first. He has good unit tests in place, and better functional tests. Faced with the same change, they've clear documentation of how the code is expected to behave. If they change it, they get immediate, direct feedback if they've broken it in some apparently unrelated area. Not without having considered the implications before making the change, obviously, but without having to have a deep understanding of the whole system, they can make sweeping changes if necessary.
This afternoon I spent an hour making some fairly hefty changes to the way the app I'm working wires itself up. That's it, an hour. This morning I knocked up a handy little class whose responsibility it now is to know in what order things need to come together, and this afternoon I reworked the builder so that you no longer had to explicitly work this out every time you used it. If I was doing this in an environment where the app hadn't been properly covered with tests, I'd still be at it well into next week.
Testing your code doesn't make you slower, it makes you faster. Sure the product is better at the end, and that's important, but the end comes sooner, and that's pretty important too, because if you never ship it, it's not worth anything to anybody.