Test Driven Development, a Portable Methodology, Page 2
The Pitfalls of TDD
Practitioners of TDD say that the advantages of it become clear once the developer gets into it. But what about pitfalls? A couple of areas of concern are with applying TDD on multi-threaded code or where a working system with much legacy code is involved.
The FAQ on testdriven.com, written by Jim Dixon, mentions that there are practitioners who say that TDD can't be used in developing multi-threaded code. Jeff Langr, author of several books on Java development, including Agile Java(TM): Crafting Code with Test-Driven Development, explains why multi-threaded code is a consideration.
With respect to multithreading: The core of the problem is that the execution sequencing of multi-threaded code is non-deterministic. Differences in things like current processor load, Java VM implementation, and OS can mean that concurrent code interleaves differently each time an application is executed.
In general, most developers have little experience in writing thread-safe code. Understanding how to write tests against multi-threaded code is even more difficult. The tests can be written, but they generally require executing multiple threads on the test side itself. There are a number of patterns that will help you write tests for things like deadlocks and race conditions. These aren't trivial tools to build. It's a significant investment, and most developers figure it's not worth the effort.
TDD shows developers that small, single purpose classes are easiest to test.
Another area where one might hesitate to rush in with TDD is an environment where a large amount of legacy code exists. Langr says that it's feasible to implement TDD in such an environment, but not without good cost. "If we never start to cover a system with unit tests, we won't be able to improve its design much (via refactoring) without high risk. Almost by definition, our system will continue to degrade in quality."
Langr says that he would introduce TDD by covering any new code with unit tests. "We won't make the system any worse than it is," he contends. Eventually, the code will be infused with pockets of tested areas. Langr recommends doing a cost analysis before attacking a project involving legacy code, the main consideration being whether or not the system will be around in six month's time.
Scott Ambler, a software process improvement (SPI) consultant, trainer and mentor of a variety of development methodologies he has founded, has his own take on tackling the challenge of legacy code. Ambler feels that it is absolutely feasible to introduce TDD into a system with a considerable amount of history. "The strategy that you want to take is to introduce your tests as you touch the code," Ambler says. The time to write the tests is whenever a procedure is updated. This way, the test suite to validate the system is built up incrementally over time. "If you have some legacy code that is mission critical, or that you're afraid to touch because it's very brittle, then you desperately need to start migrating towards a TDD-based approach for it."
Overall, the practice of TDD is becoming so widespread that no developer can afford to avoid learning it. At the very least, a future job prospect or contract gig might come down to whether or not a given developer understands TDD. "Good, clean code that works" is an attractive promise. Software development can build a foundation with unit testing, whether using XP as a development methodology or plucking TDD from its crown.
Additional Resources and Further Reading
- Test-Driven Development by Example by Kent Beck
- Test-Driven Development, A Practical Guide by David Astels
About the Author
Nancy Corbett is a freelance writer, living in the greater Seattle area. She has worked as a UNIX Systems Administrator for small development shops and large wireless telecommunications companies for over ten years.
# # #