by Jon Udell

Test before you leap into development

analysis
Aug 1, 20035 mins

Take a test-driven approach, and your engineers will better design software and engage in risk-free refactoring

Programmer and author Dave Johnson shared an anecdote on his Weblog last year about what happened when his 5-year-old son walked up behind him while he was coding. “He saw the JUnit green bar on the screen,” Johnson reports, “and said ‘Dad, you did good.’ ” There’s more to this touching father-and-son moment than meets the eye. The idea that software development can proceed by tackling a sequence of small tasks — the successful completion of which is evident even to a child — is fueling a groundswell of interest in the so-called “xUnit” testing frameworks (see sidebar) and in a companion work style called “test first” or “test driven.”

Practitioners of TDD (test-driven development) typically align themselves with one or another of the “agile” methodologies — most notably, XP (eXtreme Programming) — and use software tests in an unconventional way. Historically, IT has thought that the people who write code can’t, or shouldn’t, be responsible for testing it. In many ways that’s still a good rule of thumb. QA (quality-assurance) testers will always be needed to find problems — poor user interfaces, slow response under load, or incorrectness — that programmers have overlooked. TDD doesn’t put them out of a job.

“If you’re the head of QA and you hear that your developers are working test-first,” says Ward Cunningham , an independent consultant pioneering the approach, “you should think, ‘Good for them — now we can focus on the truly diabolical tests instead of worrying about these dead-on-arrival problems,’ ” (see “XP pioneer stumps for test-first programming”).

TDD solves a different set of problems. It does so by proposing that before you write any nontrivial piece of production code, you write tests that the code will at first fail, and then when written correctly, will pass. TDD advocates say this approach has two major benefits.

First, because the tests embody specific uses of the yet-unwritten software, they will help tease out the design of the software, complementary to other techniques such as requirements specification and modeling. Second, the tests create a safety net, enabling the programmer to engage in the risky but necessary practice of refactoring — continuously reorganizing the code — without fear of breakage. One of XP’s tenets is that change is the only constant. As the business environment evolves, so do the requirements it imposes on software. Although software is in theory perfectly malleable, in practice we are often afraid to change it. TDD seeks to reduce that fear by controlling the risk associated with change.

Serious practitioners of TDD write a lot of tests. Kent Beck, author of Test Driven Development: By Example, notes that one project done in the TDD style amounted to 250,000 lines of production code and an equal number of lines of test code. Others confirm that this one-to-one ratio is typical. Can this really be economical?

Your mileage may vary for all sorts of reasons. Some programmers take to TDD like ducks to water, others don’t (for more on this idea, see our exclusive interview with Brian Marick , founder of Testing Foundations). Some projects support more fluid business environments than others and must evolve not only during development but also while in use.

If outsourcing is part of your development strategy, it’s incredibly useful to know that your software can be modified safely by new teams. When we interviewed Glen Snyder, vice president of engineering at Natick, Mass.-based edocs, for “Leveraging a Global Advantage,” he stressed the value of a testing safety net.

“A developer working here in Natick can easily modify code written by a guy in Sri Lanka,” Snyder says. “We build every hour against our tests, and when somebody needs to make a change, they trust the tests to tell them if they did something bad.”

Developers increasingly rely on components, and now Web services, created by other developers. Here TDD can have a dual benefit. Writing a quick series of tests to exercise some unknown code is a great way to learn what the code really does, as opposed to what it’s documented to do. The resulting tests can then be used to assure that, as the component or service evolves, it continues to behave in the expected ways.

It doesn’t cost much to try TDD on a modest scale. The xUnit tools are freely available for many programming languages (see Unit testing for Java and .Net made simple). Individual developers within your organization can choose to start using them and, quite probably, some already are. But TDD doesn’t replace stress, load, usability, and acceptance testing. So if TDD takes hold, you’ll want to consider how to integrate it with these conventional techniques. Cunningham’s FIT (Framework for Integrated Test) is one such effort; it aims to connect business analysts and their acceptance tests to the TDD process.

TDD may also reveal new uses for conventional testing tools. Deborah Kablotsky, director of product management and customer support at RadView Software in Burlington, Mass., notes that although her company’s products focus on load testing, their underlying engine is a general-purpose scriptable emulator. “It can instantiate Java classes and exercise things on a component level,” she says, “and it can emulate communication protocols like HTTP or JDBC.” Here’s how TDD could mesh with that technology: To practice TDD effectively, tests have to be quick and easy to write. But setting up a complex environment — with databases and networks in predictable configurations — is arduous. Conventional testing tools that specialize in simulating real-world conditions could help lower TDD’s activation threshold.

TDD doesn’t claim to be a silver bullet. It’s just a simple, common-sense approach to doing what programmers have always known they should do: Test early and often. Nobody would argue that you shouldn’t adopt these good habits. The question is how to sustain them. For a growing number of software professionals, the combination of xUnit tools and test-first methods are proving to be a good answer.