Objects First |

There are other special values which it is always wise to include
in test data sets because of their special properties:
|
Mathematically, these special values are
known as the identities for various operations.
0 is the identity for addition because:
for any value of x. Similarly, 1 is an identity for multiplication, since for any value of x. In general, any number system, eg the complex numbers, has identities under operations that are permitted on its members. |
Thus the test data for the function:
int sort( int data[], int n );should include data sets for which n is 0 (and 1). In this case, the specification of the function will tell you what should happen when sort( d, 0 ); is called. The specification could be written in two ways:
int sort( int data[], int n );
/* Pre-condition: (n > 0) &&
(data != NULL) */
/* Post-condition: returns sorted array
in data and
error code as return value
*/
| In this case, the pre-condition states that it's the caller's responsibility to ensure that n>0. This means that the behaviour of sort is not specified for n<=0 - thus any behaviour (including a program crash) is in accordance with the specification. However, our design strategy requires that the implementation of the function should have an assertion checking each pre-condition. Thus the test data should verify that the assertion is raised for n<=0, when the program is running in "debug" mode. Naturally, what happens after the assertion is raised is irrelevant - most implementations of assert will terminate once the "assertion failed" message is printed out, because further computation is assumed, quite reasonably, to be pointless. |
int sort( int data[], int n );
/* Pre-condition: (data != NULL) */
/* Post-condition: returns sorted array
in data and
n as return value, with n<0
indicating an error;
n=0 on input returns 0 and
does nothing
*/
| Here, the behaviour for n=0 is specified. (It is often useful to have your library functions handle null cases in a defined and predictable way as many algorithms will reduce a problem to a null case. This could avoid large numbers of statements checking pre-conditions in users' programs.) | Both of these examples are acceptable coding practice. The important thing is that the function's behaviour is unambiguously specified: in the first case, it is unambiguous about where the responsibility for n=0 cases lies - with the caller! |
Test data is best placed in program tables or files. This ensures that it is easy to expand the test set, when:
and even,
It's the uncommon and rare case that you forget to test that will arise at the most inconvenient time - or provide the loop-hole for the unscrupulous!Thorough and careful analysis of the tests which must be performed is the only way to eliminate the timebombs from your code!
Key terms |
| Continue on to Test Data Examples | Back to the Table of Contents |