Tdd Is Only One Piece Of The Puzzle

I posted this to the serverside in a thread about a TDD article by Dan North (

As Dan says, TDD is a tactical thing. When you’re in the middle of coding, it helps keep you from adding unnecessary complexity, and it let’s you see how your code is going to be used even before it is.

However, that’s only part of the story. The other pieces are enough design (up front or otherwise), and merciless refactoring later.

If you don’t continuously think about where you’re going and how things fit together, and if you don’t keep your code clean by refactoring constantly, all the testing in the world is not going to give you a good architecture. To come up with a good overall system architecture, especially on large projects, you do have to think at least a little about what direction you’re going to go in ahead of time. The beauty of good unit testing is that it’s not a big deal when you’re wrong (because you will be, even if you’re right today, you’ll be wrong when you get those new requirements.)

TDD helps you design the detailed stuff right the first time, and enables you to fix the bigger stuff later.

In a system with very low duplication and high automated test coverage, you don’t have to get it right the first time, because changing your mind later is about as expensive as changing it earlier. If you haven’t worked on such a system, you should, it’s such a different experience. No matter how dramatic a change you make, in a few seconds you know if you broke anything.

Only unit testing can give you a system like this, because any other testing introduces duplication. Say you have 500 automated end to end tests with 95% test coverage. Let’s forget the fact that it takes you an hour to run them all. Suddenly there are changes to the code that you can no longer make, because they would break so many of the tests that the team couldn’t afford the time to fix them all. So crud in the code builds up, or the tests get thrown away. Either way, BAD.

Unit tests on the other hand can be and should be as fine grained as possible so that most changes no matter how radical don’t affect many tests. You can use techniques like mocking to help in this. Ideally, a test should test exactly one method/class/small chunk of functionality, and it shouldn’t break if anything else changes.

And TDD does scale. I’ve seen teams of 30 developers with suites of 1000’s of unit tests that run in less than a minute. And their code stays maleable. When people think of a way to make it better, they can. In fact I wouldn’t work on a team that size if people weren’t writing tests, because the code would deteriorate into spaghetti.

For the record, I also am a huge advocate of having testers and other types of testing: acceptance, integration, end-to-end, functional, exploratory, etc. These all can come in very handy and find holes in your product, unit tests and requirements.

Tags: ,

Comments are closed.