Black-Box and White-Box Testing Techniques Example in Detail
Consider a simple function that calculates the grade based on the marks provided as input:
1. Black Box Testing Techniques
a. Equivalence Class Partitioning (ECP)
Objective: Divide the input domain into equivalent classes where the behavior of the system
is expected to be the same.
Equivalence Classes:
1. Valid Classes:
o Marks between 0 and 59 → "F"
o Marks between 60 and 69 → "D"
o Marks between 70 and 79 → "C"
o Marks between 80 and 89 → "B"
o Marks between 90 and 100 → "A"
2. Invalid Classes:
o Marks less than 0 → "Invalid"
o Marks greater than 100 → "Invalid"
Test Cases:
1. Valid Input: Marks = 95 (Expecting "A")
2. Valid Input: Marks = 85 (Expecting "B")
3. Valid Input: Marks = 75 (Expecting "C")
4. Valid Input: Marks = 65 (Expecting "D")
5. Valid Input: Marks = 55 (Expecting "F")
6. Invalid Input: Marks = -5 (Expecting "Invalid")
7. Invalid Input: Marks = 105 (Expecting "Invalid")
Significance: By using Equivalence Class Partitioning, we test representative values from each
partition, ensuring that each partition behaves as expected.
b. Boundary Value Analysis (BVA)
Objective: Focus on testing at the boundaries between equivalence classes.
Test Cases:
1. Lower Boundary: Marks = 0 (Expecting "F")
2. Just Above Lower Boundary: Marks = 1 (Expecting "F")
3. Upper Boundary of F: Marks = 59 (Expecting "F")
4. Just Above Boundary of F: Marks = 60 (Expecting "D")
5. Lower Boundary of A: Marks = 90 (Expecting "A")
6. Just Below Boundary of A: Marks = 89 (Expecting "B")
7. Just Below Invalid Range: Marks = -1 (Expecting "Invalid")
8. Just Above Invalid Range: Marks = 101 (Expecting "Invalid")
Significance: Boundary Value Analysis ensures that the code correctly handles edge
conditions where errors are most likely to occur.
c. Orthogonal Array Testing
Objective: Use a structured combinatorial testing approach to minimize the number of test
cases while maximizing coverage.
For this example, consider a more complex version of the calculate_grade function with
additional parameters, such as marks, attendance, and extra_credit:
Parameters:
• Marks: 0-100 (3 levels: 50, 75, 90)
• Attendance: 0-100% (3 levels: 50%, 75%, 90%)
• Extra Credit: 0-10 (2 levels: 0, 5)
Using an Orthogonal Array for these parameters:
Orthogonal Array Table:
Test Case Marks Attendance Extra Credit
1 50 50% 0
2 50 75% 5
3 75 50% 5
4 75 90% 0
5 90 75% 0
6 90 90% 5
Significance: Orthogonal Array Testing allows us to cover all pairwise interactions with a
minimal number of test cases, making it efficient for testing combinations of inputs.
2. White Box Testing Techniques
a. Basic Path Testing (Cyclomatic Complexity)
Objective: Ensure that all possible paths through the code are tested.
Code Flow Diagram:
• Path 1: marks < 0 or marks > 100 → Return "Invalid"
• Path 2: marks >= 90 → Return "A"
• Path 3: marks >= 80 → Return "B"
• Path 4: marks >= 70 → Return "C"
• Path 5: marks >= 60 → Return "D"
• Path 6: marks < 60 → Return "F"
Cyclomatic Complexity Calculation:
• Number of Edges (E): 7
• Number of Nodes (N): 6
• Cyclomatic Complexity (CC): CC=E−N+2=7−6+2=3CC = E - N + 2 = 7 - 6 + 2 =
3CC=E−N+2=7−6+2=3
Test Cases for Independent Paths:
1. Path 1: Test with marks = -5 (Expecting "Invalid")
2. Path 2: Test with marks = 95 (Expecting "A")
3. Path 3: Test with marks = 85 (Expecting "B")
4. Path 4: Test with marks = 75 (Expecting "C")
5. Path 5: Test with marks = 65 (Expecting "D")
6. Path 6: Test with marks = 55 (Expecting "F")
Significance: Basic Path Testing ensures that each independent path is tested, ensuring that all
logic in the code is exercised.
Steps to Draw CFG:
1. Nodes: Represent points in the code where control flow can change.
2. Edges: Represent the flow of control from one node to another.
CFG Representation:
• Node 1 (Start): Entry point into the calculate_grade function.
• Node 2: Condition marks < 0 or marks > 100
o True branch: Goes to Node 3 (returns "Invalid").
o False branch: Goes to Node 4.
• Node 4: Condition marks >= 90
o True branch: Goes to Node 5 (returns "A").
o False branch: Goes to Node 6.
• Node 6: Condition marks >= 80
o True branch: Goes to Node 7 (returns "B").
o False branch: Goes to Node 8.
• Node 8: Condition marks >= 70
o True branch: Goes to Node 9 (returns "C").
o False branch: Goes to Node 10.
• Node 10: Condition marks >= 60
o True branch: Goes to Node 11 (returns "D").
o False branch: Goes to Node 12 (returns "F").
• Node 13 (End): Exit point from the function.
The graph is connected as follows:
1. Start (Node 1) → Node 2
2. Node 2 (Condition) → Node 3 ("Invalid") [True branch]
Node 2 (Condition) → Node 4 [False branch]
3. Node 4 (Condition) → Node 5 ("A") [True branch]
Node 4 (Condition) → Node 6 [False branch]
4. Node 6 (Condition) → Node 7 ("B") [True branch]
Node 6 (Condition) → Node 8 [False branch]
5. Node 8 (Condition) → Node 9 ("C") [True branch]
Node 8 (Condition) → Node 10 [False branch]
6. Node 10 (Condition) → Node 11 ("D") [True branch]
Node 10 (Condition) → Node 12 ("F") [False branch]
7. All nodes lead to End (Node 13).
CFG
DD-Path Graph
The DD-Path (Decision-to-Decision Path) Graph is another representation of the code
structure, focusing on decisions and the paths that connect them.
DD-Path Graph Representation:
• DD-Path 1: Entry into the calculate_grade function (Start).
• DD-Path 2: Decision at marks < 0 or marks > 100.
• DD-Path 3: Returns "Invalid".
• DD-Path 4: Decision at marks >= 90.
• DD-Path 5: Returns "A".
• DD-Path 6: Decision at marks >= 80.
• DD-Path 7: Returns "B".
• DD-Path 8: Decision at marks >= 70.
• DD-Path 9: Returns "C".
• DD-Path 10: Decision at marks >= 60.
• DD-Path 11: Returns "D".
• DD-Path 12: Returns "F".
• DD-Path 13: Exit from the function (End).
DD-Path Graph
Cyclomatic Complexity Calculation
Cyclomatic Complexity (CC) is calculated using the formula:
Cyclomatic Complexity(CC)=E−N+2P\text{Cyclomatic Complexity}
(CC) = E - N + 2P
Where:
• E = Number of edges in the graph.
• N = Number of nodes in the graph.
• P = Exit Points
• E=13 (Number of edges)
• N=12 (Number of nodes)
• P=1
CC=13−12+2(1)=3
The Cyclomatic Complexity is 3, indicating there are 3 independent paths through the
program. Each of these paths should be tested to ensure full path coverage.
b. Control Structure Testing
Objective: Test all control structures like conditions, loops, and data flows within the code.
Condition Testing:
• Test the condition marks < 0 or marks > 100 with both true and false outcomes.
• Test marks >= 90, marks >= 80, marks >= 70, and marks >= 60 with both true and false
outcomes.
Test Cases:
1. Marks = -5 (Condition marks < 0 is True, expecting "Invalid")
2. Marks = 105 (Condition marks > 100 is True, expecting "Invalid")
3. Marks = 95 (Condition marks >= 90 is True, expecting "A")
4. Marks = 85 (Condition marks >= 80 is True, expecting "B")
5. Marks = 75 (Condition marks >= 70 is True, expecting "C")
6. Marks = 65 (Condition marks >= 60 is True, expecting "D")
7. Marks = 55 (Condition marks < 60 is True, expecting "F")
Dataflow Testing:
Track the usage of the marks variable throughout the code and ensure its value is used correctly
in all conditions.
Loop Testing:
Since there are no loops in this function, loop testing does not apply.
Significance: Control Structure Testing ensures that all conditions and data flows are correctly
handled in the code.
c. Code Coverage
Objective: Ensure that every part of the code is executed during testing.
Statement Coverage:
• Ensure every statement in the code is executed.
• Test with a variety of inputs to hit all conditions (e.g., marks = 55, 65, 75, 85, 95, -5,
105).
Decision Coverage:
• Ensure every decision (if statement) is tested for both true and false outcomes.
Branch Coverage:
• Ensure that every possible branch (outcome of an if statement) is tested.
Condition Coverage:
• Ensure that every condition in the if statements is tested for both true and false.
Significance: Code Coverage ensures that no part of the code is left untested, increasing the
reliability of the software.
d. Program Slicing
Objective: Isolate and test specific parts of the code to understand how they affect the output.
Example:
• Forward Slice: From the condition if marks >= 90, slice the code that affects the output
when marks are greater than or equal to 90.
• Backward Slice: From the return statement, slice the code that affects the grade
calculation.
Test Cases:
• Marks = 95 (Sliced code should correctly return "A")
• Marks = 85 (Sliced code should correctly return "B")
Solution: Program Slicing helps in understanding the dependencies in the code, making
debugging easier and more focused.
Also, static and dynamic slicing can be considered.