www.delorie.com/gnu/docs/avl/libavl_77.html   search  
 
Buy GNU books!


GNU libavl 2.0.1

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.14 Testing

Whew! We're finally done with building functions for performing BST operations. But we haven't tested any of our code. Testing is an essential step in writing programs, because untested software cannot be assumed to work.

Let's build a test program that exercises all of the functions we wrote. We'll also do our best to make parts of it generic, so that we can reuse test code in later chapters when we want to test other BST-based structures.

The first step is to figure out how to test the code. One goal in testing is to exercise as much of the code as possible. Ideally, every line of code would be executed sometime during testing. Often, this is difficult or impossible, but the principle remains valid, with the goal modified to testing as much of the code as possible.

In applying this principle to the BST code, we have to consider why each line of code is executed. If we look at the code for most functions in &#60;@xref{\NODE\, , bst.c.&#62;,25}, we can see that, if we execute them for any BST of reasonable size, most or all of their code will be tested.

This is encouraging. It means that we can just construct some trees and try out the BST functions on them, check that the results make sense, and have a pretty good idea that they work. Moreover, if we build trees in a random fashion, and delete their nodes in a random order, and do it several times, we'll even have a good idea that the bst_probe() and bst_delete() cases have all come up and worked properly. (If you want to be sure, then you can insert printf() calls for each case to record when they trip.) This is not the same as a proof of correctness, but proofs of correctness can only be constructed by computer scientists with fancy degrees, not by mere clever programmers.

There are three notably missing pieces of code coverage if we just do the above. These are stack overflow handling, memory allocation failure handling, and traverser code to deal with modified trees. But we can mop up these extra problems with a little extra effort:(8)

The testing code can be broken into the following groups of functions:

Testing and verification
These functions actually try out the BST routines and do their best to make sure that their results are correct.

Test set generation
Generates the order of node insertion and deletion, for use during testing.

Memory manager
Handles memory issues, including memory leak detection and failure simulation.

User interaction
Figures out what the user wants to test in this run.

Main program
Glues everything else together by calling functions in the proper order.

Utilities
Miscellaneous routines that don't fit comfortably into another category.

Most of the test code will also work nicely for testing other binary tree-based structures. This code is grouped into a single file, &#60;@xref{\NODE\, , test.c.&#62;,97}, which has the following structure:

 
&#60;@xref{\NODE\, , License.&#62;,1}
#include &#60;assert.h&#62;
#include &#60;limits.h&#62;
#include &#60;stdarg.h&#62;
#include &#60;stdio.h&#62;
#include &#60;stdlib.h&#62;
#include &#60;string.h&#62;
#include &#60;time.h&#62;
#include "test.h"
&#60;@xref{\NODE\, , Test declarations.&#62;,121}
&#60;@xref{\NODE\, , Test utility functions.&#62;,134}
&#60;@xref{\NODE\, , Memory tracker.&#62;,126}
&#60;@xref{\NODE\, , Option parser.&#62;,586}
&#60;@xref{\NODE\, , Command line parser.&#62;,589}
&#60;@xref{\NODE\, , Insertion and deletion order generation.&#62;,642}
&#60;@xref{\NODE\, , Random number seeding.&#62;,643}
&#60;@xref{\NODE\, , Test main program.&#62;,140}

The code specifically for testing BSTs goes into &#60;@xref{\NODE\, , bst-test.c.&#62;,98}, outlined like this:

 
&#60;@xref{\NODE\, , License.&#62;,1}
#include &#60;assert.h&#62;
#include &#60;limits.h&#62;
#include &#60;stdio.h&#62;
#include "bst.h"
#include "test.h"
&#60;@xref{\NODE\, , BST print function.&#62;,119}
&#60;@xref{\NODE\, , BST traverser check function.&#62;,104}
&#60;@xref{\NODE\, , Compare two BSTs for structure and content.&#62;,106}
&#60;@xref{\NODE\, , Recursively verify BST structure.&#62;,113}
&#60;@xref{\NODE\, , BST verify function.&#62;,109}
&#60;@xref{\NODE\, , BST test function.&#62;,100}
&#60;@xref{\NODE\, , BST overflow test function.&#62;,122}

The interface between &#60;@xref{\NODE\, , test.c.&#62;,97} and &#60;@xref{\NODE\, , bst-test.c.&#62;,98} is contained in &#60;@xref{\NODE\, , test.h.&#62;,99}:

 
&#60;@xref{\NODE\, , License.&#62;,1}
#ifndef TEST_H
#define @cindex TEST_H macro
TEST_H 1
&#60;@xref{\NODE\, , Memory allocator.&#62;,5}
&#60;@xref{\NODE\, , Test prototypes.&#62;,101}
#endif /* test.h */

Although much of the test program code is nontrivial, only some of the interesting parts fall within the scope of this book. The remainder will be listed without comment or relegated to the exercises. The most tedious code is listed in an appendix (see section B. Supplementary Code).

5.14.1 Testing BSTs  
5.14.2 Test Set Generation  
5.14.3 Testing Overflow  
5.14.4 Memory Manager  
5.14.5 User Interaction  
5.14.6 Utility Functions  
5.14.7 Main Program  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster   donations   bookstore     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003