Path Coverage
10.2.4 Path Coverage
The criterion of path coverage provides that we generate test data to exercise every execution path of candidate programs. If the program has no loops, then the set of paths is finite, and can be easily catalogued; to get a sense of the work involved in this task, we consider the two versions of the triangle analysis program (the nested version and the sequential version). The flow chart of the nested version looks as follows (Fig. 10.2).
Paths in the program correspond to paths from the first node to the exit node in this graph; covering all the paths corresponds, in this case, to branch coverage. We
Cout << “enter..”; Cin >>x>>y>>z;
!tri(x,y,z) T
Cout << “not a triangle”;
Equi(x,y,z)
Cout << “equilateral”; Iso(x,y,z)
Right(x,y,z)
Cout << “isosceles
Cout << “isosceles”;
right”;
Right(x,y,z) T
Cout << “right”;
Cout << “scalene”;
Exit
210 STRUCTURAL CRITERIA
characterize each path by the sequence of conditions that it evaluates as it proceeds from the start to the exit node, and we find the following paths.
Test Data Path
Condition x
tri()&& equi()
1 1 2 p4
tri() && !equi() && iso() && right()
4 4 3 p5
tri()&& !equi() && iso() && !right()
3 4 5 p6
tri() && !equi() && !iso() && right()
tri() && !equi() && !iso() && !right()
We consider now the sequential version of the triangle analysis program (Fig. 10.3). Topologically, this flowchart appears to have 2 6 paths, since it has six binary conditions in sequence; but in fact many of these paths are not executable (their path function is empty) due to the dependencies between the conditions. If we identify each path by the sequence of True/False (T/F) values of the conditions, we find the following paths:
Path
!tri equi
tri && !equi &&
!iso &&
!equi && iso && tri && !iso
iso && !right
right
right && !right
Notice that in this table, each row is fully determined by the shaded area. For exam- ple, in the first row (path p1), consider that if condition (!tri) returns True, then all subsequent expressions necessarily return False: for example, the second column (condition: equi) returns False since a set of three identical numbers define a triangle; the third column (condition: tri && !equi && iso && !right) returns False since the first conjunct (tri) is already known to be False; etc. Hence the paths p1, p2, p3, p4, p5,
p6 presented in this table are the only feasible paths (out of 2 6 ) of the program. The following table characterizes each one of these paths and proposes a data item that falls in their domain.
10.2 CONTROL FLOW COVERAGE 211
Cout << “enter the triangle…”; cin >> x >> y >> z;
!tri(x,y,z) TF
Cout << “not a triangle”;
Equi(x,y,z)
Cout << “equilateral”;
Tri && !equi && iso && !right
TF Cout << “isosceles”;
!iso && right
TF
Cout << “right”;
!equi && iso && right
TF Cout << “right isosceles”;
tri && !iso && !right
TF Cout << “scalene”;
Exit
Figure 10.3 Flowchart of a Triangle program: sequential version.
Path Path Condition Test Data
tri && !equi && iso && !right
334 (continued)
212 STRUCTURAL CRITERIA
(continued) p4
345 p5
!iso && right
3332 p6
!equi && iso && right
tri && !iso && !right
The sample examples we have studied so far have a finite number of paths, since they have no iterative statements; with while loops, we face the possibility of having an infinite number of paths; for such cases the criterion of path coverage cannot be fulfilled to the letter. We resort to approximations of this criterion, whereby we con- sider upper bounds on the number of iterations for each loop. Because we may have nested loops, even this approximate criterion may cause a combinatorial explosion, producing up to N p paths, where N is the upper bound on the number of iterations and p is the depth of nesting of the loops.
As an example, we consider the gcd program discussed in Section 10.1:
{int x; int y; read(x); read(y); // assuming x>0, y>0 while (x!=y) {if (x>y) {x=x-y;} else {y=y-x;}}; write(x);}
We resolve to apply the path coverage criterion to it, up to three iterations of the while loop. We find the following paths, classified according to the number of iterations:
• Path with Zero iterations:
○ p0: int x; int y; read(x); read(y); ((x!=y)? false); write(x);
• Paths with One iteration:
○ p11: int x; int y; read(x); read(y);
((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? false); write(x);
○ p12: int x; int y; read(x); read(y); ((x!=y)? true); ((x>y)? false); y=y-x;
((x!=y)? false); write(x);
• Paths with Two iterations:
○ p21: int x; int y; read(x); read(y);
((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? false); write(x);
10.2 CONTROL FLOW COVERAGE 213 ○ p22: int x; int y; read(x); read(y);
((x!=y)? true); ((x>y)? false); y=y-x; ((x!=y)? true); ((x>y)? false); y=y-x; ((x!=y)? false); write(x);
○ p23: int x; int y; read(x); read(y);
((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? true); ((x>y)? false); y=y-x; ((x!=y)? false); write(x);
○ p24: int x; int y; read(x); read(y); ((x!=y)? true); ((x>y)? false); y=y-x;
((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? false); write(x);
• Paths with Three iterations: In order to keep combinatorics under control, and because x and y play symmetric roles, we do not show all eight paths; but rather only four; the missing four can be retrieved by interchanging x and y.
○ p31: int x; int y; read(x); read(y);
((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? false); write(x);
○ p32: int x; int y; read(x); read(y);
((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? true); ((x>y)? false); y=y-x; ((x!=y)? false); write(x);
○ p33: int x; int y; read(x); read(y);
((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? true); ((x>y)? false); y=y-x; ((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? false); write(x);
○ p34: int x; int y; read(x); read(y);
((x!=y)? true); ((x>y)? true); x=x-y; ((x!=y)? true); ((x>y)? false); y=y-x; ; ((x!=y)? true); ((x>y)? false); y=y-x; ((x!=y)? false); write(x);
We leave it as an exercise to the reader to compute the path functions and the path conditions of these paths; we show the results in the table below, along with test data that meets the path conditions.
214 STRUCTURAL CRITERIA
Test data Number of iterations
2x=3y
p24
3x=2y
2x=5y
p33
3x=5y
p34
3x=4y
The test data for the four missing paths resulting from three iterations can be computed by merely interchanging x and y in the test data of the paths of length 3; we find,
Test data Number of iterations
2y=5x
p33
3y=5x
p34
3y=4x