Black-Box Testing Techniques
Black-box testing does not consider the internal structure of the system. Test cases are derived from the external specification, which describes what the system should do. This approach is used in system and integration testing.
Because testing every input is impossible, black-box testing uses techniques that select a small number of tests to represent a larger set of possibilities.
Technique 1: Equivalence Class Partitioning
This technique divides the domain of input values into groups called equivalence classes. Within each class, the system behaves in the same way.
When creating classes:
- Consider both valid and invalid input values.
- Keep equivalence classes for valid and invalid inputs separate.
- Select one representative value from each class for testing. If this value works, all other values in its class should also work.
Example: getAbsoluteValue(int num)
A specification for a function that gets the absolute value of an integer might have these rules:
- If the argument is not negative, it is returned.
- If the argument is negative, its negation is returned.
- A special case notes that if the argument is
Integer.MIN_VALUE, the result isInteger.MIN_VALUE(which is negative).
This specification leads to three equivalence classes for the input num:
| Class Name | Values | Representative |
|---|---|---|
| non-negative | \(0 \le \texttt{num} \le \texttt{Integer.MAX\_VALUE}\) | 10 |
| negative-not-min | \(\texttt{Integer.MIN\_VALUE} < \texttt{num} < 0\) | -5 |
| min-value | \(\texttt{num} = \texttt{Integer.MIN\_VALUE}\) | Integer.MIN_VALUE |
This reduces the full range of possible integers to just three representative cases.
Technique 2: Boundary Value Analysis
This technique complements equivalence partitioning. Program errors are more likely to occur at the boundaries of partitions.
Boundary value analysis identifies the partitions and then tests the values on the boundary and their immediate neighbors.
Example: getAbsoluteValue(int num) Boundaries
Using the same classes from before, we can identify the following boundaries and create test cases for them:
- For <code>non-negative</code> (\(0 \le \texttt{num} \le \texttt{MAX}\)): Boundaries are 0 and
Integer.MAX_VALUE. - For <code>negative-not-min</code> (\(\texttt{MIN} < \texttt{num} < 0\)): Boundaries are
Integer.MIN_VALUE + 1and-1. - For <code>min-value</code> (\(\texttt{num} = \texttt{MIN}\)): The boundary is
Integer.MIN_VALUE.
This creates test cases for catching off-by-one errors.
Technique 3: Decision Tables
When input combinations become complex and lead to different outcomes, a decision table is a formal way to describe the interactions.
The table is split into Conditions (inputs) and Reactions (outputs/actions). Each column represents a single rule or test case, and the goal is to generate one test per column.