Test-driven Development makes significant changes in how you are
accustomed to working as a programmer. (For more details,
click here.) Before you write a line of
production code, you write an automated unit test that serves as
an "executable spec" for that code. You then write just enough
production code to get that test to pass. Then you
refactor the
test code and the production code, striving for more simplicity
and clarity.
This new way of working takes
some getting used to, and a leap of faith before you even get started.
Can it possibly work? What's the payoff? Is it worth it?
Perhaps this sounds familiar: You work with a large
codebase. Thousands of lines of code, some of it healthy, some of
it not so healthy. The code contains
more and more dependencies, and
a fair amount of duplicate code, dead code, or wasteful code.
You have to work in this code every day, but small changes can
have big nasty side-effects. Testing cycles take too long.
Bugs take longer and longer to find and fix. Integration takes too long.
The code exhibits more design smells each month. It just gets
harder and harder to work with.
And there never seems to be time to clean it all up properly.
We believe the only way to rescue rotting code
is with sound OOD principles, TDD, and refactoring. Each class can be isolated
for extension from other classes and resources whenever those
dependencies prove unhealthy. TDD is the most systematic way to accomplish this.
And each class can be isolated
for unit testing from all other classes and resources,
using techniques and tools such as fakes and mock object frameworks.
Refactoring and test retrofitting, though painstaking at first,
is incremental and systematic. You can see the code steadily getting fixed, and
you don't have to completely
trash your current production schedule to do it.
TDD is more than worth it. You can produce new code that is nearly defect-free.
Your designs are simpler, accommodating change more easily. You can often
finish new code faster with TDD. You
can slowly but surely wrestle intractable legacy systems into a state
that lets you extend and maintain them predictably and fearlessly.
And you can take more risks and try more experiments with the code,
to find the best design or squeeze out the best performance. This is because the
whole time you work, your automated tests prove that the code functions
properly.
[Read More]
|