Data Structures and Algorithms


Boundary Values

Here is the original code:
char upcase( char x ) {
  if ( (x > 'a') && (x < 'z') )
    return x + ('A'-'a');
  else return x;
  }
Of course, you immediately spotted that it should have been:
char upcase( char x ) {
  if ( (x >= 'a') && (x =< 'z') )
    return x + ('A'-'a');
  else return x;
  }

Experienced programmers know that certain errors, like writing '>' rather than '>=' are so easy to make and so easy to miss on inspection of code, that they will treat the boundary cases as separate equivalence classes. This expands the equivalence classes to:
values of x
  • in ('b','y'),
  • 'a',
  • 'z',
  • less than 'a' and
  • greater than 'z'

If I had not seen the code and was generating test cases for this case from the specification, then I would assume that the programmer would use the order of the ASCII characters, but I wouldn't know whether he or she had chosen to write:

if ( (x<='`') || (x>='{') ) return x;
else ...
so I would include values on both sides of the boundary just as a precaution.

Further extension of the boundary value argument would suggest that the values: 0, -1, any other negative value, 255, 256 and a value > 256 should be added to check that extremities of the legal range are correctly processed also.

Special Values

Tests should invariably include 0 (as either a boundary value or because it is the identity under addition) as a "special value" even if the formal analysis suggests that it belongs to some other class. It is particularly unwise to use 0 as a representative of any class (except itself!) because of its special properties under arithmetic operations. Similar considerations apply to 1.

Other domains have their special values, which should be routinely included also:

Illegal values

Illegal values may be excluded by the pre-condtions, but in systems where assertion mechanisms are available, you should be testing that assertions are raised when they should be also! You want to make sure that you can rely on the assertions to detect errors in functions that use this function!

While not formally required, these few extra tests - added because I know something about how the program is likely to be constructed - do no harm (and may save you if a programmer - at some later stage - decides to change the implementation, makes a mistake doing it and forgets to change the test suites also!). The important consideration here is that these extra tests have been added because we know something about typical programming errors or ways that the function could be changed. They are not just random values which could all lie in the middle of some equivalence class and represent totally useless tests!

Outputs

Outputs should be formed into equivalence classes also and test cases should be designed to ensure that a representative of each output class is produced.

Again boundary and special values need to be included: for instance your test set for a word processor should include



Back
Table of Contents
© John Morris, 1996