Defect-Free Software
Steps to Defect-Free
FAQ: Defect-Free
Automated QA
Site Index

Nine Steps to Delivering Defect-Free Software

Copyright © 1997, 1998 Terence M. Colligan

Hello. I am Terry Colligan, president of Tenberry Software, Inc. I have been a software developer for over 30 years, and have been managing software development for over 20 years. Tenberry Software (formerly Rational Systems) has a reputation for producing high-quality software and for having extremely good engineers.

Although I thought I understood the importance of quality, and took pride in the quality of the software we produced, I never believed that delivering defect-free software was possible. After all, everyone knows that all software has lots of bugs, right?

Well, no, not necessarily! Certainly, most experiences with today's software quality are not encouraging. Although few people can name even one piece of software which they use that has no bugs, defect-free software is possible to create. We know it is possible, because we're doing it.

It started with a single engineer. This engineer was consistently producing work with a defect rate more than one hundred times smaller than our other engineers. She has done so for us for over three years now. During the same time, she has produced three to five times as much code as any other engineer.

I found this so exciting that I determined to find out how she did it, and to see if we could teach our other engineers to achieve the same quality results.

I later discovered that one of my best friends, an independent consultant in the mainframe/Cobol world, has been similarly producing defect-free results on his projects.

We have developed a process to produce guaranteed defect-free software. (We are continuing to refine our process, but it works now.) To help improve general software quality, we are sharing the nine steps of our process:

1. Believe Defect-Free Software is Possible

Surprisingly, the first reaction that I get when I describe Defect-Free Software is to be told that it's just not possible. Defect-Free Software seems to be self-contradictory. Some folks even act as if "Defect-Free Software" is an attempt at computer humor.

In fact, this attitude is the biggest obstacle preventing the delivery of defect-free software! The most striking difference between the two defect-free engineers and our other engineers (including me!) is their attitude towards software defects.

The average engineer acts as though defects are inevitable. Sure, they try to write good code, but when a defect is found, it's not a surprise. No big deal, just add it to the list of bugs to fix. Bugs in other people's code are no surprise either. Because typical engineers view bugs as normal, they aren't focused on preventing them.

The defect-free engineers, on the other hand, expect their code to have no defects. When a (rare) bug is found, they are very embarrassed and horrified. When they encounter bugs in other people's code, they are disgusted. Because the defect-free engineers view a bug as a public disgrace, they are very motived to do whatever it takes to prevent all bugs.

In short, the defect-free engineers, who believe defect-free software is possible, have vastly lower defect rates than the typical engineer, who believes bugs are a natural part of programming. The defect-free engineers have a markedly higher productivity.

In software quality, you get what you believe in!

2. Think Defect-Free Software is Important

Why is defect-free software important?

  • Delivering defect-free software reduces support costs.

  • Delivering defect-free software reduces programming costs.

  • Delivering defect-free software reduces development time.

  • Delivering defect-free software can provide a competitive advantage.

If you (or your manager) don't think delivering defect-free software is important, you won't spend the effort necessary to deliver it.

3. Commit to Delivering Defect-Free Software

In the past, I was the single biggest obstacle to producing defect-free code at Tenberry. Because I didn't really believe that defect-free code was possible, I made decisions primarily focused on short schedule times.

In retrospect, virtually every decision against trying for defect-free and in favor of short schedule time was wrong and resulted in longer schedules, more bugs, more support, higher costs and smaller profits!

Making a firm commitment to defect-free code and holding to that commitment, in spite of schedule and other pressures, is absolutely necessary to producing defect-free code.

As a nice side benefit, you will see improved schedules and reduced costs!

4. Design Your Code for Simplicity and Reliability

After attitude and commitment, program design and structure have the biggest impact on defect-free code. A clean, well structured design simplifies producing reliable code. A poor design cripples the engineer, and will make it impossible to achieve defect-free code.

Each function should be precise -- it should have only one purpose. Each action or activity should be implemented in exactly one place. When programs are structured this way, the engineer can easily find the right place to make a change. In the unlikely event that a bug is discovered in testing, the engineer can go directly to the code with the defect and promptly correct it. This saves time and is the major cause of the faster schedules experienced with Defect-Free Software.

In addition to designing for clarity, it's important to keep the defect-free goal in mind. You want to choose designs that will be least likely to have bugs. In other words, avoid tricky code. Don't start to optimize code unless you are sure there is a performance problem.

5. Trace Every Line of Code When Written

To me, one of the most surprising techniques used by our defect-free engineer was the deliberate tracing in a debugger of each line of new code when it is written.

As each line of code is about to be executed, you should try to predict what the effect will be -- what data will be changed, which path a conditional will follow, etc. If you can't predict what the effect will be, then you don't understand the program you are working on -- a very dangerous situation. If you don't predict correctly, you have probably discovered a problem that should be addressed.

Tracing all new code shows:

  • Code that hasn't been tested. By stepping through each line of code, you ensure that the new code is fully tested.

  • Inefficient code. For example, calling the same function multiple times. The first time engineers watch a trace of their code, they are often surprised to see exactly how much redundant and inefficient code is executed.

  • Code that is working for the wrong reason.

  • Confirmation that the design is functioning as intended.

Tracing all new code will ensure that your code will be tested and is functioning as designed -- both important characteristics of defect-free code.

6. Review Code by Programmer Peers

Peer code reviews have consistently been shown to be the single most cost-effective way of removing bugs from code. The process of explaining a new section of code to another engineer and persuading that second engineer the code is defect-free has several positive impacts:

  • Exposes the design and implementation, with benefits similar to tracing the code.

  • Forces the engineer to articulate assumptions. About ten percent of our code reviews are stopped in progress as the authoring engineer suddenly says, "Oops! Never mind!" because he suddenly realized that he had made an invalid assumption. (The review later resumes with the revised code.)

  • Allows more than one engineer to look at the code while it can still be easily changed. Code will be made simpler and easier to understand.

  • Encourages cross-training and sharing of techniques. By discussing design strategies and implementation techniques, each engineer learns from the experience of their peers.

Peer code reviews seem to work best. Code reviews done by managers or senior technical staff can have some of the same benefits, but sometimes are less effective due to the interpersonal dynamics.

7. Build Automated QA into Your Code

Obviously, to build defect-free code, you have to be able to test your code. In addition to including a testing plan/strategy into the implementation, you should design specific code to provide for full, automated testability.

The most effective testing we use is fully automated or regression testing. This is a series of fully automated tests that are run after each build of a program. The tests are designed to exercise every part of the program, and produce a success/failure report. The idea is to use the power of the computer to make sure that the program hasn't been adversely affected by a change.

If the design is well structured, most changes should not have side effects. The purpose of these automated tests is to provide insurance that the coding assumptions are valid, and that everything else still works. By making the tests completely automated, they can be run frequently and provide prompt feedback to the engineer.

If tests are run by manually testing the program, we have the chance of human error missing a problem. Manual testing is also very expensive, usually too expensive to run after every change to a program.

There are a number of commercial testing tools available which are designed to help you automate your testing, particularly in GUI environments such as Windows. Although they are no doubt better than manual testing, we have not found them to be effective, for a number of reasons. (For more details, check out our automated testing strategy.)

By building support for automated testing into your program, you can approach 100% automated testing. Without this customized, built-in testability, you will be lucky to achieve 35% automated testing, even with the best commercial QA testing tool. We recommend that you budget five percent of total engineering time to creating support for automated QA testing.

Of course, each new piece of code should have a corresponding set of tests, added at the same time as the code is added, for the automated QA suite.

In order for fully automated execution of testing to be of value, the tests that are automatically executed and checked must cover the software fully. To the extent that they don't, running the tests doesn't tell you anything about the part of your software that wasn't exercised by the testing. (This is true for all testing, whether automated or manual.)

8. Build and Test Daily

Once you have a fully automated test suite, you should run it after every build. This gives developers feedback about the changes they are making, and it gives management clear, objective feedback about the project status.

Clear, objective feedback about project status help managers make better estimates and plans. This feedback can help you identify and address problems while you still have time to do something about them. In addition, this clear, objective feedback puts managers in a better position to provide correct feedback to their managers (or shareholders). Finally, this objective feedback helps managers decide when a project can be shipped or deployed.

The more prompt the feedback to the programmers, the more useful it is. The shorter the time between the creation of a defect and its discovery, the easier it is for the programmer to understand just what they have done wrong. Prompt feedback of failing tests can work as a kind of positive reinforcement for development techniques that work and negative reinforcement for techniques that don't.

By automating the build process as well, you can schedule builds of your system daily. By building daily, you will maximize the feedback to both your programmers and your management.

9. Use Automated Checking Wherever Possible

There are a lot of existing tools that can be used to find errors in your code in an automatic or semiautomatic manner. Your programmers should be using these tools wherever possible.

These tools should be used in addition to the clean design, rather than instead of. No matter how much you use automated checking tools, using these tools alone will never turn poorly designed, buggy code into defect-free code. You can however, find a lot of bugs that would otherwise take much more time and effort to find and fix.

Useful automated checking tools include:

  • Setting your compiler's warning level to maximum.

  • Using the memory trace subsystem, such as Microsoft's MFC/DBGWIN combination, that may be provided with your compiler.

  • Lint. This is a program which does extra fussy checking of C code. Some people find it very helpful. There is a PC version and a C++ version available from Gimpel Software.

These kinds of tools are important, particularly for catching the kinds of errors that don't have obvious symptoms, such as memory leaks.


That's the overview of how we create defect-free software. Obviously, there is a lot of work involved. There are also lots of details that will need to be adapted to your specific situation.

Applying these defect-free methods to an existing program will be worthwhile as well. Although it's harder to achieve a totally defect-free result with existing code (usually due to the design), applying these steps will result in a significant reduction in an existing program's defect rates.

You can deliver defect-free software -- all you have to do is demand it. By following these steps and working constantly towards the defect-free goal, you will see more and more of your software become defect-free.

Tenberry helps companies deliver defect-free software in two ways: We produce defect-free software under contract, and we consult with companies to help them produce their own defect-free software processes.

To discuss Tenberry's Defect-Free implementation of your software project or to start your own process towards Delivering Defect-Free Software, contact our sales department at the address below. You'll be glad you did!

Tenberry Software, Inc.
P.O.Box 20050, Fountain Hills, AZ 85269, USA
1.480.767.8709 fax
1.480.767.8868 phone

For more information on Tenberry's Automated QA and other products and services, contact our sales department.

[Home] * [Consulting Services] * [DOS/4G] * [DOS/4GW] * [DOS/16M] * [Rational Systems]
Last modified 2002.6.05. Your questions, comments, and feedback are welcome.