|
Driven to Test to Success
As we wind down this year of economic uncertainty, I want to end on a positive note. I cannot establish government policy, but I can recommend a simple practice that can improve how effectively you meet your organization's quality goals. Test Driven Development (TDD), also known as Test First Programming, is a way to unit test software in an efficient and continuous manner. For developers, TDD is an opportunity to become a better programmer and designer. For managers and project management, TDD gives you direct visibility into your team's progress, and the quality status of their code base. Someone wrote that, "A test worth writing is a test worth saving". So, TDD is an automated technique that assures you maintain your investment in your unit tests, eliminates human variation in conducting tests, and redirects developers' resistance to unit testing. It is axiomatic in the waterfall process that developers cannot test their own code. The reason for this is simple: after a developer constructs the project code, they cannot easily turn around and try to tear down that same code by testing it. They have invested too much intellectual capital into building the software. Asking them to break it is impractical. This resistance is a psychological barrier to quality, not a technical obstacle. But the result of insufficient, or non-existent, unit testing is that local logic and coding errors are passed downstream to system test, a qualitatively different form of testing that can find unit defects only if they surface during system and functional testing. TDD contributes improvement in all of these areas:
TDD can do this because it changes the relationship between coding and testing. In the traditional, waterfall approach to unit testing, requirements specify the goals of the project, production code is written to satisfy those requirements, then unit tests are defined and executed manually to verify that the production code performs as expected. The following graphic illustrates these relationships:
In TDD, requirements still specify the goals of the project. But in TDD we first write executable tests that quantify the requirements. Then we write the production code that satisfies those tests. The graphic below illustrates this:
You can see that TDD reverses the relationship between the coding and unit test activities. It also reverses the psychological constraints on the developer. In the traditional approach the developer performs a constructive activity of building the code, then performs a destructive activity of attempting to break the same code. In TDD the developer performs a constructive activity of building the test code based on quantifiable properties of the requirements, then performs another constructive activity of building the production code that enables the test to succeed. Two positives, no negatives. The practice of TDD is deceptively simple. It only requires the developer to do the following steps:
Why must the test fail in step 3 above? This is the exquisite simplicity of TDD, which is also the most puzzling concept to newcomers. In step 2 you write the executable test code, but you do not write any production code yet. In step 3 you run the test code and it has to fail for two reasons:
Another benefit of TDD is a bit subtle. When you write the tests, and then the production code, those tests are users of your production code. TDD lets you think about your production code and its interfaces from the perspective of a user, i.e. from client code that is invoking your code. What better way to make sure your interfaces, method names, and argument lists are usable than to design them as a user! TDD frameworks are referred to as "xUnit" frameworks, and are available for most languages. Some that may be compatible with your development languages are:
TDD lets you take large, or very small, steps in how you arrive at the final version of each test method. And at each step you can write a lot, or just a little, production code to satisfy the current goals of each test method. Once you write the unit tests, you have them forever. As your project requirements change, so will the unit tests, and so will the production code. But having the tests is everything. When you have 85 unit tests working against your production code, and you are getting "green" bars, you feel good. But you feel even better when you know that if you make a code error that causes a working test to fail, you will get a "red" bar alerting you to the failed test. That gives you confidence. With TDD you are never more than a few seconds away from knowing if all your production code still passes the tests. That is very cool, and it's a great idea with which to end a year, and an even better idea for beginning a new year. Have a pleasant holiday season, Gary K. Evans |
Subscribe to our newsletter! Send an email to Immediate and Productive Results Evanetics is committed to fighting project waste, and to supporting your team with pragmatism derived from decades of project experience. If you want immediate progress, and a partner who is committed to having 'skin in the game', please contact me. I welcome an opportunity to talk with you about your goals. Evanetics provides comprehensive on-site training, consulting and assessments for teams and management in Business Analysis, Project Definition, Iterative process, RUP, Agile principles and practices. Tools Slow You Down I won't give up my compiler or programming editor. Without these tools, no software is going to be developed. But I spend a lot of time on projects doing UML modeling. The modeling tools we have available today are more capable, configurable and cost-effective than their ancestors ever were. But, ironically, I use these tools less now than I did in those good ol' days. It is certainly not because I do not understand these tools. In the past 6 years I have written reviews of at least a dozen modeling and development tools. I am cautious in using these tools because over-relying on them causes them to become a drag on the pace of a fast-moving project. In an agile, or even a seriously iterative, project, software is being developed daily to meet the goals of an iteration that may be only 2-3 weeks in duration. In the beginning of such a project, the entire project team is in discovery mode. We are groping to understand the system rather than actually knowing what it should be. I have found on every one of my projects that our models - especially class diagrams and sequence diagrams - are changing daily, even hourly, in the early iterations. Trying to keep our current thinking in a software modeling tool is an exercise in frustration, not engineering. On one project we went through 28 distinct versions of just the class diagram - and that was in only the first 8 weeks of the project. Over these years I have learned that the fastest tool in my arsenal is a series of very large whiteboards, and lots of markers. The team starts modeling on one board and eventually fills all of them. Then we erase the oldest and least accurate models (an LRU algorithm, right?) and continue. Eventually the models stabilize: the changes become smaller, less profound, and less frequent. Then, and only then, we transcribe these stable models into a modeling tool for archival and presentation purpose. Trying to keep rapidly-changing models, or documents, continually up to date is always a challenge. I have learned to let my modeling or CASE tool - or wordprocessor - be a benefit to our projects by relying on them less, and using them to best advantage: letting them capture and present what we have already discovered, not being a liability to the act of discovery. |
|
Published by: Evanetics, Inc.13 Stonebriar Road Columbia, SC 29212 803-781-7628 Copyright (C) 2008 Evanetics, Inc. All rights reserved. www.evanetics.com |
|