2004-07-01
| Rate This Article: | Add This Article To: |
Test-Driven Development (TDD) is a central component of eXtreme Programming (XP), but is also used on its own, outside of this rigid software development methodology. With TDD, you focus on how to test your code before you even start writing it. It's a quite methodical approach, wherein you write a test, write code until it passes the test, write your next test, and so on. Rather than throwing out old tests as you go along, you let them accumulate. That makes it easy to tell whether adding a new piece of code broke something you set up previously.
As you might imagine, this technique works best with code that can be definitively tested. Libraries, for example, are good candidates. They're simple and straightforward, offering a limited set of returned results. More open-ended components are far more difficult. (In other words, TDD only works with code that you can actually test.) However, projects that don't lend themselves completely to TDD at least can have components that are suited (again, like libraries). Making sure that the underlying pieces of a complex project are thoroughly tested can help to make debugging the overall product easier, overall.
TDD Benefits
The simplest way to break down Test-Driven Development is through the sequence: test, code, and refactor. There is no up-front design time; you're focusing on features. You follow the process until the first feature works, then focus on the next, and so on. In general, according to the paper, About the Return on Investment of Test-Driven Development, the development phase of a TDD project is longer than development in a project not using the same methodology. However, the QA phase is considerably shorter since many of the bugs were worked out up front.
Another paper, An Initial Investigation of Test Driven Development in Industry, agrees with this finding, adding that “it is conjectured that the resulting high quality of code written using the TDD practice may be due to the granularity of TDD, which may encourage more frequent and tighter verification and validation.” The authors appear to find that TDD simply makes programmers more likely to write the automated tests—used for repeatedly checking to make sure that errors weren't introduced—in the first place. Programmers who waited to write tests until after the code was complete didn't always get around to it, leading to “inadquate testing.” In fact, only one of the six control pairs bothered to write “any worthwhile automated test cases” even after being explicitly told to do so. (Presumably, this is nothing like you've ever experienced. Right.)
It is easy to see how this would appeal to companies or projects with no budget for additional QA staff. They can use TDD to improve code quality before ever reaching the testing phase.
However, there are other, less obvious benefits. Here's one: if you focus on functionality that must work, you are not distracted by features that you think might be useful—thus, leading to a more focused development effort. Plus, if you do automated testing at every step in your project, it's far easier to find the source of a newly introduced problem. Testing at the end of the development cycle can mean poring over thousands of lines of code, trying to determine what went wrong.
TDD Drawbacks and Additional Considerations
TDD can't solve every code quality problem, however, especially when you don't apply it wisely. Those running the second study ran into an interesting problem: “We expected that professional programmers would write code that handled all error conditions gracefully. However, after analyzing the results of our first trial, we found this not to be the case.” In the battery of three experiments run for this study, the first experiment had specific criterion that a program had to test successfully for—just as in TDD. However, what this rule set resulted in was code that was only written to pass the specifications. A programming culture in which “all error conditions [are handled] gracefully” (such as always testing for buffer overruns or incorrect input as a matter of course) is also required to get the most benefit out of Test-Driven Development.
You can also lose speed and efficiency benefits when you're dealing with programmers who are unfamiliar with TDD. If your company intends to move toward a TDD approach, then it's worth designating a specific project (or series of projects) as the time to try out the Test-Driven Development ropes. Using the methodology with smaller projects that are well-suited to TDD lets you train your existing staff; when it's time for a larger, complex project, you will get the full benefits. It can also be beneficial to bring someone on board who already has experience with TDD—either on a permanent or temporary basis—to help facilitate the learning process. This factor is especially true if you combine TDD with pair programming, or the full eXtreme Programming suite of practices.
After all, don't forget that TDD is a part of XP. To ease your staff into using XP for projects where it's suited, you can start by teaching them TDD, then perhaps pair programming, and so on, rather than forcing them to leap into the deep blue waters of XP with no prior experience with any of its many methodologies.
Experienced programmers are already familiar with “best practices” that ultimately boil down to making sure to test your code routinely. However, as the pressure to perform increases (or the energy the developer puts into the work decreases), implementing TDD practices can help to ensure that devlopment teams properly test the code at all before it heads off for the QA process. You have to go into this with the understanding that TDD code can take longer to develop, and you'll need to reinforce management expectations that solid code takes longer to write. However, if the QA process is shorter, the project's time-to-market doesn't have to be adversely affected. Focus on these aspects, and many managers will be hard-pressed to argue against this approach. Just be sure to chose TDD for the types of projects it is best suited for. If you can't test it, you can't use TDD.
|
![]() |
|


