Identifying the Test Cases
The second step is the use of equivalence
classes to identify the test cases. The process is as
follows:
- Assign a unique number to each equivalence class.
- Until all valid equivalence classes have been covered by
(incorporated into) test cases, write a new test case
covering as many of the uncovered valid equivalence classes
as possible.
- Until your test cases have covered all invalid
equivalence classes, write a test case that covers one, and
only one, of the uncovered invalid equivalence classes.
The reason that individual test cases cover
invalid cases is that certain erroneous-input checks mask or
supersede other erroneous input checks. For instance, if the
specification states "enter book type (HARDCOVER, SOFTCOVER,
or LOOSE) and amount (1-999)," the test case, XYZ 0,
expressing two error conditions (invalid book type and amount)
will probably not exercise the check for the amount, since the
program may say "XYZ IS UNKNOWN BOOK TYPE" and not bother to
examine the remainder of the input.
Boundary-Value Analysis
Experience shows that test cases that explore
boundary conditions have a higher payoff than test cases that
do not. Boundary conditions are those situations directly on,
above, and beneath the edges of input equivalence classes and
output equivalence classes. Boundary-value analysis differs
from equivalence partitioning in two respects:
- Rather than selecting any element in an equivalence
class as being representative, boundary-value analysis
requires that one or more elements be selected such that
each edge of the equivalence class is the subject of a test.
- Rather than just focusing attention on the input
conditions (input space), test cases are also derived by
considering the result space (output equivalence classes).
It is difficult to present a "cookbook" for
boundary-value analysis, since it requires a degree of
creativity and a certain amount of specialization toward the
problem at hand. (Hence, like many other aspects of testing,
it is more a state of mind than anything else.) However, a few
general guidelines are as follows:
- If an input condition specifies a range of values, write
test cases for the ends of the range, and invalid-input test
cases for situations just beyond the ends. For instance, if
the valid domain of an input value is -1.0-+1.0, write test
cases for the situations -1.0, 1.0, -1.001, and 1.001.
- If an input condition specifies a number of values,
write test cases for the minimum and maximum number of
values and one beneath and beyond these values. For
instance, if an input file can contain 1-255 records, write
test cases for 0, 1, 255, and 256 records.
- Use guideline 1 for each output condition. For instance,
if a program computes the monthly FICA deduction and if the
minimum is $0.00 and the maximum is $1,165.25, write test
cases that cause $0.00 and $1,165.25 to be deducted. Also,
see if it is possible to invent test cases that might cause
a negative deduction or a deduction of more than $1,165.25.
Note that it is important to examine the boundaries of the
result space because it is not always the case that the
boundaries of the input domains represent the same set of
circumstances as the boundaries of the output ranges (e.g.,
consider a sine subroutine). Also, it is not always possible
to generate a result outside of the output range, but it is
worth considering the possibility, nonetheless.
- Use guideline 2 for each output condition. If an
information- retrieval system displays the most relevant
abstracts based on an input request, but never more than
four abstracts, write test cases such that the program
displays zero, one, and four abstracts, and write a test
case that might cause the program to erroneously display
five abstracts.
- If the input or output of a program is an ordered set (a
sequential file, for example, or a linear list or a table),
focus attention on the first and last elements of the set.
- In addition, use your ingenuity to search for other
boundary conditions.
|