In This Issue:
- Examining Test-Driven Development
- Book Review: The Inmates are Running the Asylum
- Hot Links
Examining Test-Driven Development
Test-driven development (TDD) is the combination of test first development (TFD) and refactoring. TFD is an evolutionary development technique where you write a unit test before writing just enough production code to fulfill that test. Refactoring is a development technique where you make a change to the design of your code or database schema which improves its quality without changing its semantics.
The first step of TDD is to ask the question "Is this the best design possible which enables me to add this functionality?" If so, then continue. If not, then refactor the design so that it is the best one possible and then continue. The second step of TDD is to quickly add a test, basically just enough code to fail. Next you run your tests, often the complete test suite although for sake of speed you may decide to run only a subset, to ensure that the new test does in fact fail. You then update your production code to make it pass the new tests. Then you run your tests again. If they fail you need to update your functional code and retest. Once the tests pass you start over.
There are several reasons why you should consider adopting TDD.
- It forces you to think through the design of your code before you write it, thereby specifying it in detail.
- As the name implies, TDD is a great way to validate your code.
- Another common view is that TDD is simply a programming technique. As Ron Jeffries likes to say, the goal of TDD is to write clean code that works.
TDD is clearly a technique which your organization should consider adopting, yet lately there has been some debate in newsgroups and blogs as to TDD's value. I've noticed that these discussions revolve around several misconceptions which I attribute either to people simply not having any real-world experience with TDD and/or they've listened to some of the more fervent rhetoric surrounding the technique. These misconceptions are:
- You create a 100-percent regression test suite. Although this sounds like a good idea, and it is, unfortunately it isn't realistic for several reasons.
- First, you may have some reusable assets which do not come with a test suite, nor perhaps even with source code. Although you should create black-box tests which validate the interface of an asset these tests won't completely test it.
- Second, the user interface of a system is really hard to test. Although user interface testing tools do in fact exist, not everyone owns them and sometimes these tools are difficult to use. Like traditional teams, many agile teams leave user interface testing to their manual user testing efforts.
- Third, database regression testing is a fairly new concept and not yet well supported by tools.
- Fourth, you may be working on a legacy system and simply haven't gotten around to writing all of the required tests (something that you should do in an evolutionary, as needed manner).
- The unit tests form 100 percent of your design specification. People new to agile software development, or people claiming to be agile but who really aren't, will sometimes say this. The reality is that your unit tests form a large part of your design specification, and similarly acceptance tests form a portion of your requirements specification, but there's more to it than this. As the Agile Modeling methodology shows, agilists do in fact model and write documentation--it's just that we're very smart about how we do it. With TDD you'll still need external documentation describing your design, but significantly less than what you would need on a traditional project.
- You only need to unit test. This is obviously false for all but the most simplistic of systems. The agile community is very clear about the need for acceptance testing, user testing, system integration testing, and a host of other testing techniques.
- TDD doesn't scale. This is partly true, although straightforward to address.
- One common scalability issue is that your test suite takes too long to run. The solution is to separate your test suite into two components, one that contains the tests for the functionality that you're currently working on and the other which contains all tests. You run the first test suite regularly, migrating older tests for mature portions of your production code to the complete test suite as appropriate. The overall test suite is run in the background, often on a separate machine(s), and/or at night.
- A second common "scalability issue" is that not all developers in your organization know how to test. This is a simple problem to solve: Get them some appropriate training and get them pairing with people with unit testing skills.
- Third, some people on the team aren't taking a TDD approach. In order of preference, the way to address this problem is either to get everyone to start doing so, "motivate" the dissenters to leave the team, or your team should give up on TDD.
My experience is that TDD has become the norm within the agile software development community and has also been adopted by many "traditional" developers as well. TDD should be seen as complementary to modeling approaches, and as I've argued with AMDD the two can and should be used together. TDD does not replace traditional testing, instead it defines a proven way to ensure effective unit testing. A side effect of TDD is that the resulting tests are working examples for invoking the code, thereby providing a working specification for the code. Once you wade through the common myths and misconceptions, you'll find that TDD works incredibly well in practice and it is something that all software developers should consider adopting.
Book Review: The Inmates Are Running the Asylum
In The Inmates Are Running the Asylum, Alan Cooper indicates that many of today's software-based products suffer from usability challenges. He believes that the key to solving the problem is to perform what he calls interaction design before the programming effort to design the way that software behaves before it is built. Cooper believes programmers consciously design the code inside programs but only inadvertently design the interaction with humans. Although programmers work hard to make their software easy to use, their frame of reference is themselves and as a result they make it easy for other software engineers, not normal human beings. He argues that programmers have too much influence over the design of the human interface and due to a lack of skills in this area do a poor job of it. In other words, the programming inmates are running the software development asylum.
Although this is one of those rare books which all IT professionals should read, you need to take Cooper's process-oriented recommendations with a grain of salt. Reading between the lines of both this book and a debate between Kent Beck and Alan Cooper (see below), it seems to me that most of Cooper's experiences are with traditional development teams but not agile teams. Although I believe that his observations about the interaction design skill levels of developers apply to both the traditional and agile communities, I fear that his advice is difficult for traditionalists to implement and all but impossible for agilists. My experience is that it is possible to take an agile, if not evolutionary approach to usability activities on a software development project, and I eagerly await a future update to this book discussing this very concept.
The Inmates are Running the Asylum: Why High-Tech Products Drive Us Crazy and How to Restore the Sanity
by Alan Cooper
SAMS Publishing, 2004
For a detailed introduction to Test-Driven Design (TDD), see http://www.agiledata.org/essays/tdd.html
The Full Lifecycle Object-Oriented Testing (FLOOT) method reveals the wide range of testing techniques available to you: Unit testing is just one of many. See http://www.ambysoft.com/essays/floot.html
Extreme Programming vs. Interaction Design is a debate between Kent Beck and Alan Cooper regarding the applicability of interaction design techniques to agile software development projects
Considering unit tests to be detailed design specifications, and acceptance tests as requirements specifications, are examples of the agile practice Single Source Information. See http://www.agilemodeling.com/essays/singleSourceInformation.htm for details.
A Roadmap for Regression Testing of Relational Databases describes in detail how to go about database regression testing. See http://www.agiledata.org/essays/databaseTesting.html
The Agile Alliance homepage is the best starting point for anyone interested in learning more about agile software development http://www.agilealliance.com
The Agile Models Distilled page provides links to overviews of a wide variety of models at http://www.agilemodeling.com/artifacts
The principles of Agile Modeling v2 are described at http://www.agilemodeling.com/principles.htm
The practices of Agile Modeling v2 are described at http://www.agilemodeling.com/practices.htm
Check out the Agile Modeling mailing list at http://www.agilemodeling.com/feedback.htm
Get agile modeling training resources at http://www.agilemodeling.com/training.htm