Defensive Programming

Author: Kurt Stephens ks.icstars_AT_kurtstephens_DOT_com
Date: 2004/05/13
Version: $Id: index.html,v 1.5 2002/07/10 06:50:35 stephens Exp $


Introduction

This is located at http://www.kurtstephens.com/icstars/wshop/src/fun_Defensive_Programming/index.html.

Tar archive is located at fun_Defensive_Programming.tar.gz.

Defensive Programming is the use of programming techniques to prevent problems before they occur.

  1. If anything can go wrong it will. ("Murphy's Law")
    The only thing you can truly expect is the unexpected.
  2. You are going to make mistakes and lots of them.
  3. Since you are going to be making many mistakes, learn from them.
    When you repair a problem:
    Try to anticipate common problems and prevent them.
  4. Since other people will probably make the same mistakes as you, prevent them from making them again.
  5. Learn from other's mistakes.
    To be a good story writer you need to read a lot of stories.
  6. Since you will make mistakes often, make small tools to help you find and prevent them.

Defects and Faults

Defects are errors in the software itself. A fault is a problem that arises from a defect. Some defects never cause faults (attributed to defects in testing!). All faults are caused from at least one defect. "Bug" is common synonym for defect.

The term "computer bug" is usually attributed to Admiral Grace Hopper of the US Navy, who worked on some of the early computers, found the first "actual bug in computer" in 1945. A moth crawled inside a electro-mechanical relay in a computer and caused a short-circuit. The term "bug" was also used in 1896 for electrical circult problems.

Instrumentation

Instrumentation is little bits of code added to a program to get a better understanding of how it behaves.

Assignment #1:

You've just started your first job at Commerical Bank. You've been a given a simple account processing program to fix.  See Account.cs.

There are a number of defects in the program.

First, calculate the expected balance by hand (or with a calculator) by reading the list of deposit() and withdrawl() calls at the end of the program.

Compile and run the program to compare the expected balance with the result of the program.

Assignment #2:

To figure out how the program works you will "instrument" the program so you can see what parts of the program are used.

A simple instrumentation might be to print the name of the class and method and the arguments and result value at the beginning and the end of the method body.

Non-instrumented:

publc class YourClass
{
public static double aMethod(double anArgument)
{
double result;

result = anArgument + 123.45;

return result;
}


Instrumented:

public class YourClass
{
public static double aMethod(double anArgument)
{
double result;

Console.WriteLine("DEBUG: METHOD: BEGIN: aMethod({0})", anArgument);

result = anArgument + 123.45;

Console.WriteLine("DEBUG: METHOD: END: aMethod({0}) => {1}", anArgument, result);

return result;
}
}

See Account2.cs for an instrumented version of Account.cs.

Debug Helper Class

A debug helper class can be used to make adding instrumentation easier.

Assignment #3:

Make a Debug helper class to print the method instrumentation for you.

public class Debug
{
public static void methodBegin(object class, string method, object arg1)
{
Console.WriteLine("DEBUG: METHOD: BEGIN {0}.{1}({2})", class, method, arg1);
}

public static void methodEnd(object class, string method, object result)
{
Console.WriteLine("DEBUG: METHOD: END {0}.{1}(...) => {2}", class, method, result);
}
}

public class YourClass
{
public static double aMethod(double anArgument)
{
double result;

Debug.methodBegin("YourClass", "aMethod", anArgument);

result = anArgument + 123.45;

Debug.methodEnd("YourClass", "aMethod", result);

return result;
}
}

See Debug.cs for an example of a helper class.
See Account3.cs for an example using the Debug class.

Interface Defects

Interface defects occur when one part of a program uses another part incorrectly.

The Account.cs program has (at least) 5 interface defects. Can you find them?

Assertions

An assertion is a short test in a program that validates that the program is doing what was intended and designed for.

Pre-conditions

Conditions that must be true at the beginning of a function.

public static double divide(double x, double y)
{
double result;

Debug.assert("y != 0", y != 0);

result = x / y;

return result;
}

See Account4.cs for an example with assertions added.

Post-conditions

Conditions that must be true at the end of a function.

Assignment #4:

What assertions (pre-conditions) should be added to prevent the interface defects?

Make a Debug helper class to instrument and handle assertions.

Other Exercises:

  1. Fix Account4.cs
  2. Change your Debug class to conditionally print instrumentation.
  3. Change the Account.cs program to read a file that contains line with either deposits "DEP xxx.xx", or withdrawls "WTH yyy.yy".
  4. Write a program that inserts instrumentation code into your programs.

References

Programming Pearls, Jon Bentley, Addison-Westley, ISBN 0-201-65788-0

More Programming Perls, Jon Bentley, ISBN: 0-201-11889-0

The Practice of Programming, Brian W. Kernighan, Rob Pike, ISBN 0-201-61586-X

Links

http://www.jamesshuggins.com/h/tek1/first_computer_bug.htm

http://www.history.navy.mil/photos/pers-us/uspers-h/g-hoppr.htm

http://www.geocities.com/xtremetesting/TestingDictionary.html

http://www.it.nuigalway.ie/~j_duggan/courses/ct216/CT216-Testing/

http://hissa.nist.gov/latex/node10.html

http://www.testingfaqs.org/tools.htm

http://adl.opengroup.org/