Unit test requires testing both the unit’s internal structure and its behavioral characteristics. Testing the internal structure requires knowledge of how the unit is implemented, and tests based upon this knowledge are known as white-box tests. Testing a unit’s behavioral characteristics focuses on the external observable behaviors of the unit without knowledge or regards its implementation. Tests based upon this approach are referred to as black-box tests. Deriving test cases based upon both approaches are described below.
White-Box / Glass-Box Tests:
Theoretically, you should test every possible path through the code. Achieving such a goal, in all but very simple units, is either impractical or almost impossible. At the very least you should exercise every decision-to-decision path (DD-path) atleast once, resulting in executing all statements at least once. A decision is typically an if-statement, and a DD-path is a path between two decisions.
White box testing is a test case design method that uses the control structure of the procedural design to derive test cases. Test cases can be derived that
1. Guarantee that all independent paths within a module have been exercised at least once.
2. Exercise all logical decisions on their true and false sides.
3. Execute all loops at their boundaries and within their operational bounds.
4. Exercise internal data structures to ensure their validity.
To get this level of test coverage, it is recommended that you choose test data so that every decision is evaluated in every possible way. Toward that end, the test cases should make sure that:
Every Boolean expression is evaluated to true and false. For example the expression (a < 3) or (b > 4) evaluates to four combinations of true / false.
Every infinite loop is exercised atleast zero times, once and more than once.
Use code-coverage tools to identify the code not exercised by your white box testing. Reliability testing should be done simultaneously with your white-box testing.
Example:
Independent Paths:
Path 1: 1-11
Path 2: 1-2-3-4-5-10-11
Path 3: 1-2-3-6-8-9-10-11
Path 4: 1-2-3-6-7-9-10-11
Each new path introduces a new edge these paths comprise a BASIS SET – every statement in the program guaranteed to be executed at least once
Cyclomatic Complexity tells us: size of the BASIS set
For a flow graph: V (G) = E – N + 2
Where: E = Edges
N = Nodes
Also, V (G) = P + 1
Where: P = Number of Predicate Nodes
White Box - Deriving Test Cases (Path Coverage):
Read code, draw a flow graph.
Determine Cyclomatic Complexity.
Determine a basis set of Independent Paths.
Prepare the Test Cases that force execution of each path.