The best candidates for rapid development are systems for which requirements remain constant throughout the lifetime of the project. Sadly, such projects are a rarity, possibly to the extent that like such mythical beasts as the Yeti and the Loch Ness monster, their existence is questionable at best, and most likely fictitious.
Software projects have proven themselves prone to change at even the latest stage of the development process. A change can strike a project from a variety of directions: requirements are subject to change when use cases are enhanced, removed, or added; the system design may also change, either to reflect an update to the requirements or because of an initial discrepancy or shortcoming. Furthermore, an application's code base is constantly in a state of flux, as mistakes are made and rectified, and enhancements and optimizations are applied.
We've already covered techniques that seek to both assess the impact of change and mitigate its disruptive effects. Models offer a low-cost option for measuring the consequences a change will have on the ability of the design to execute the system, while code generation helps build an adaptive foundation for the project in order that changes can be absorbed without unduly stretching out the project schedule. We've seen that a layered design is also important, as it confines the potential ripple effects of a change to a single part of the architecture.
Another software engineering method can be added to this arsenal of techniques to further strengthen the base of our adaptive foundation: test-driven development.
Test-driven development is an approach in which the project is protected from change by a shield of unit tests. In this chapter, we examine the benefits of test-driven practices for rapid development and identify how testing techniques contribute to productivity and agility.
The testing activity is critical to the successful delivery of a software system, and we discuss over the next two chapters the various aspects of the testing process and the role it plays in rapid development.
The focus of this chapter is on the advantages and application of test-driven development, and we introduce the unit-testing framework JUnit. Methods for the autogeneration and running of unit tests are covered, as are the role of mock objects in the testing process.