views:

99

answers:

2

The situation: millions of lines of code, more than one hundred developers and frequent defects. We want to avoid repeating defects and we want to improve code design (who doesn't?).

Test Driven Development (first unit test, then code) sounds ideal: write a test case for each function.

But, with so much code written, how can TDD be implemented? Where do you start - with low level functions?

Or are we too late to start TDD?

+10  A: 

Start with Working Effectively with Legacy Code.

It's not really TDD if you're starting with legacy code - but all your coding can be TDD. As you tackle a new problem, write a test for it. If you can't, because the legacy classes are too difficult to test, then start writing tests for them, slicing off bits, and covering the bits with tests.

Refactor the Low-Hanging Fruit.

To avoid repeating defects: given an example defect, write a test that demonstrates it. It could be a relatively broad test that just simulates user activity; not yet a unit test. Make sure the test fails. Do your research; figure out why the test is failing. Now - this is important - before fixing the bug, write a unit test that demonstrates the bug. Fix the bug, and now you've got two tests, at least one of them fast, that protect you from regressions.

Carl Manaster
+1: The key here is to *not* try and comprehensively retrofit unit tests.
Richard
Mark Robinson
@Richard - I'm puzzled - isn't that the opposite of what Carl is saying?
Mark Robinson
@Mark, I think Richard and I agree; the key is "comprehensively". If you go through a legacy code base and try to cover everything before moving forward, you wind up getting nowhere (and with nothing to show for it). Tackle just the bits you need to work on; over time, your system becomes reasonably well-tested, and along the way, you're adding functionality (or at least removing bugs).
Carl Manaster
@Carl add something, also about adding tests to areas where you are adding new functioniality
Gutzofter
@Carl - yes, I understand now, thanks. And I agree - no point going through everything at once - stick to what is adding value. (After all - a study into Lean development showed that more than half the code we develop is never used!)
Mark Robinson
@Gutzofter - definitely, otherwise you just add tests to legacy code... then your new code quickly becomes legacy code! :)
Mark Robinson
+1  A: 

Since Carl suggested one book I'll suggest another: Roy Osherove's Art of Unit Testing has a whole chapter on "Working with legacy code". I haven't read that chapter yet, but the first 5 chapters are excellent, and I'm looking forward to it.

orbfish
FYI I enjoyed Osherove's comparison of definitions for legacy code:"source code that relates to no-longer-supported technology""any older application under maintenance""code that works""code that has no tests" (from Feathers's book)
orbfish
@Carl thanks for the C2 link, that's hilarious.
orbfish
@Orbfish - Thanks for the tip. Perhaps when you've read it you'll come back and share some insights?
Mark Robinson