Overview Graph Coverage
Criteria
Module 3
Introduction to Software Testing
Graph Coverage for Source Code
Overview
• The most common application of graph criteria is to
program source
• Graph : Usually the control flow graph (CFG)
• Node coverage : Execute every statement
• Edge coverage : Execute every branch
• Loops : Looping structures such as for loops, while loops,
etc.
• Data flow coverage : Augment the CFG
• defs are statements that assign values to variables
• uses are statements that use variables
Control Flow Graphs
• A CFG models all executions of a method by describing control
structures
• Nodes : Statements or sequences of statements (basic blocks)
• Edges : Transfers of control
• Basic Block : A sequence of statements such that if the first statement
is executed, all statements will be (no branches)
• CFGs are sometimes annotated with extra information
• branch predicates
• defs
• uses
• Rules for translating statements into graphs …
CFG : The if Statement
if (x < y)
{
y = 0; 1
x = x + 1; x<y x >= y
} y=0
x=x+1 2 3 x=y
else
{
x = y; 4
}
if (x < y) 1
{ x<y
y = 0; y=0 x >= y
x=x+1 2
x = x + 1;
}
3
CFG : The if-Return Statement
if (x < y)
{ 1
return; x<y
} x >= y
return 2
print (x);
return;
print (x)
3 return
No edge from node 2 to 3.
The return nodes must be distinct.
Loops
• Loops require “extra” nodes to be added
• Nodes that do not represent statements or basic blocks
CFG : while and for Loops
x = 0;
x=0 1
while (x < y) dummy node
{
2
y = f (x, y); x<y x >= y implicitly
x = x + 1; x=0 1
initializes loop
} 3 4
y =f(x,y)
x=x+1 2
x<y x >= y
for (x = 0; x < y; x++)
{ y = f (x, y) 3 5
y = f (x, y);
}
4 x=x+1
implicitly
increments loop
CFG : do Loop, break and continue
x = 0; x = 0;
do while (x < y) 1 x=0
{ {
y = f (x, y); y = f (x, y);
x = x + 1; if (y == 0) 2
} while (x < y); {
println (y) break; 3 y =f(x,y)
} else if y < 0) y == 0
{
y = y*2; 4 break
x=0 1 continue;
} 5
y<0
x = x + 1;
y = f (x, y) y = y*2
2 x = x+1 } 6 continue
x >= y print (y);
x<y x=x+1
7
3
8
CFG : The case (switch) Structure
read ( c) ;
switch ( c )
{
case ‘N’: 1 read ( c );
y = 25; c == ‘N’
break; c == ‘Y’ default
case ‘Y’:
y = 50; 2 3 4
y = 25; y = 0;
break; break; y = 50; break;
break;
default:
y = 0; 5
break; print (y);
}
print (y);
Example Control Flow – Stats
public static void computeStats (int [ ] numbers)
{
int length = numbers.length;
double med, var, sd, mean, sum, varsum;
sum = 0.0;
for (int i = 0; i < length; i++)
{
sum += numbers [ i ];
}
med = numbers [ length / 2];
mean = sum / (double) length;
varsum = 0.0;
for (int i = 0; i < length; i++)
{
varsum = varsum + ((numbers [ I ] - mean) * (numbers [ I ] - mean));
}
var = varsum / ( length - 1.0 );
sd = Math.sqrt ( var );
System.out.println ("length: " + length);
System.out.println ("mean: " + mean);
System.out.println ("median: " + med);
System.out.println ("variance: " + var);
System.out.println ("standard deviation: " + sd);
}
© Ammann & Offutt 11
Control Flow Graph for Stats
public static void computeStats (int [ ] numbers)
{
int length = numbers.length; 1
double med, var, sd, mean, sum, varsum;
sum = 0.0;
for (int i = 0; i < length; i++) 2 i=0
{
sum += numbers [ i ];
}
med = numbers [ length / 2]; i >= length
mean = sum / (double) length; 3
varsum = 0.0; i < length
for (int i = 0; i < length; i++)
{ i++ 4
varsum = varsum + ((numbers [ I ] - mean) * (numbers [ I ] - mean)); 5
} i=0
var = varsum / ( length - 1.0 );
sd = Math.sqrt ( var );
6
System.out.println ("length: " + length);
System.out.println ("mean: " + mean); i < length
System.out.println ("median: " + med); i >= length
System.out.println ("variance: " + var);
System.out.println ("standard deviation: " + sd); 7 8
} i++
© Ammann & Offutt 12
Control Flow TRs and Test Paths – EC
1
Edge Coverage
2 TR Test Path
A. [ 1, 2 ] [ 1, 2, 3, 4, 3, 5, 6, 7, 6, 8 ]
B. [ 2, 3 ]
3
C. [ 3, 4 ]
4
D. [ 3, 5 ]
5 E. [ 4, 3 ]
F. [ 5, 6 ]
G. [ 6, 7 ]
6 H. [ 6, 8 ]
I. [ 7, 6 ]
7 8
13
Control Flow TRs and Test Paths – EPC
1 Edge-Pair Coverage
TR Test Paths
2 A. [ 1, 2, 3 ] i. [ 1, 2, 3, 4, 3, 5, 6, 7, 6, 8 ]
B. [ 2, 3, 4 ] ii. [ 1, 2, 3, 5, 6, 8 ]
C. [ 2, 3, 5 ] iii. [ 1, 2, 3, 4, 3, 4, 3, 5, 6, 7,
3 D. [ 3, 4, 3 ] 6, 7, 6, 8 ]
E. [ 3, 5, 6 ]
4 F. [ 4, 3, 5 ] TP TRs toured sidetrips
5
G. [ 5, 6, 7 ] i A, B, D, E, F, G, I, J C, H
H. [ 5, 6, 8 ] ii A, C, E, H
6 I. [ 6, 7, 6 ] iii A, B, D, E, F, G, I, C, H
J, K, L
J. [ 7, 6, 8 ]
K. [ 4, 3, 4 ]
7 8 L. [ 7, 6, 7 ]
14
Control Flow TRs and Test Paths – PPC
Prime Path Coverage
1
TR Test Paths
A. [ 3, 4, 3 ] i. [ 1, 2, 3, 4, 3, 5, 6, 7, 6, 8 ]
2 B. [ 4, 3, 4 ] ii. [ 1, 2, 3, 4, 3, 4, 3,
C. [ 7, 6, 7 ] 5, 6, 7, 6, 7, 6, 8 ]
D. [ 7, 6, 8 ] iii. [ 1, 2, 3, 4, 3, 5, 6, 8 ]
3 E. [ 6, 7, 6 ] iv. [ 1, 2, 3, 5, 6, 7, 6, 8 ]
F. [ 1, 2, 3, 4 ] v. [ 1, 2, 3, 5, 6, 8 ]
4
5 G. [ 4, 3, 5, 6, 7 ]
TP TRs toured sidetrips
H. [ 4, 3, 5, 6, 8 ]
i A, D, E, F, G H, I, J
I. [ 1, 2, 3, 5, 6, 7 ]
6 J. [ 1, 2, 3, 5, 6, 8 ] ii A, B, C, D, E, F, G, H, I, J
iii A, F, H J
iv D, E, F, I J
7 8 v J
15
Data Flow Coverage for Source
• def : a location where a value is stored into memory
• x appears on the left side of an assignment (x = 44;)
• x is an actual parameter in a call and the method changes its value
• x is a formal parameter of a method (implicit def when method starts)
• x is an input to a program
• use : a location where variable’s value is accessed
• x appears on the right side of an assignment
• x appears in a conditional test
• x is an actual parameter to a method
• x is an output of the program
• x is an output of a method in a return statement
• If a def and a use appear on the same node, then it is only a DU-pair
if the def occurs after the use and the node is in a loop
public static void computeStats (int [ ] numbers)
Example Data Flow – Stats
{
int length = numbers.length;
double med, var, sd, mean, sum, varsum;
sum = 0.0;
for (int i = 0; i < length; i++)
{
sum += numbers [ i ];
}
med = numbers [ length / 2 ];
mean = sum / (double) length;
varsum = 0.0;
for (int i = 0; i < length; i++)
{
varsum = varsum + ((numbers [ i ] - mean) * (numbers [ i ] - mean));
}
var = varsum / ( length - 1 );
sd = Math.sqrt ( var );
System.out.println ("length: " + length);
System.out.println ("mean: " + mean);
System.out.println ("median: " + med);
System.out.println ("variance: " + var);
System.out.println ("standard deviation: " + sd);
}
Control Flow Graph for Stats
( numbers )
1 sum = 0
length = numbers.length
2 i=0
3 i >= length
i < length
med = numbers [ length / 2 ]
4 5 mean = sum / (double) length
varsum = 0
sum += numbers [ i ]
i=0
i++
6 i >= length
i < length
var = varsum / ( length - 1.0 )
7 8 sd = Math.sqrt ( var )
varsum = … print (length, mean, med, var, sd)
i++
CFG for Stats – With Defs & Uses
1 def (1) = { numbers, sum, length }
2 def (2) = { i }
3 use (3, 5) = { i, length }
use (3, 4) = { i, length }
def (5) = { med, mean, varsum, i }
4 5 use (5) = { numbers, length, sum }
def (4) = { sum, i }
use (4) = { sum, numbers, i }
6 use (6, 8) = { i, length }
use (6, 7) = { i, length }
def (8) = { var, sd }
def (7) = { varsum, i } 7 8 use (8) = { varsum, length, mean,
use (7) = { varsum, numbers, i, mean } med, var, sd }
Defs and Uses Tables for Stats
Node Def Use Edge Use
1 { numbers, sum, { numbers } (1, 2)
length } (2, 3)
2 {i}
(3, 4) { i, length }
3
(4, 3)
4 { sum, i } { numbers, i, sum }
(3, 5) { i, length }
5 { med, mean, { numbers, length, sum }
varsum, i } (5, 6)
6 (6, 7) { i, length }
7 { varsum, i } { varsum, numbers, i, (7, 6)
mean } (6, 8) { i, length }
8 { var, sd } { varsum, length, var,
mean, med, var, sd }
DU Pairs for Stats
variable DU Pairs defs come before uses, do
not count as DU pairs
numbers (1, 4) (1, 5) (1, 7)
length (1, 5) (1, 8) (1, (3,4)) (1, (3,5)) (1, (6,7)) (1, (6,8))
med (5, 8)
var (8, 8) defs after use in loop,
sd (8, 8) these are valid DU pairs
mean (5, 7) (5, 8)
No def-clear path …
sum (1, 4) (1, 5) (4, 4) (4, 5)
different scope for i
varsum (5, 7) (5, 8) (7, 7) (7, 8)
i (2, 4) (2, (3,4)) (2, (3,5)) (2, 7) (2, (6,7)) (2, (6,8))
(4, 4) (4, (3,4)) (4, (3,5)) (4, 7) (4, (6,7)) (4, (6,8))
(5, 7) (5, (6,7)) (5, (6,8))
(7, 7) (7, (6,7)) (7, (6,8)) No path through graph from
nodes 5 and 7 to 4 or 3
DU Paths for Stats
variable DU Pairs DU Paths variable DU Pairs DU Paths
numbers (1, 4) [ 1, 2, 3, 4 ] mean (5, 7) [ 5, 6, 7 ]
(1, 5) [ 1, 2, 3, 5 ] (5, 8) [ 5, 6, 8 ]
(1, 7) [ 1, 2, 3, 5, 6, 7 ] varsum (5, 7) [ 5, 6, 7 ]
length (1, 5) [ 1, 2, 3, 5 ] (5, 8) [ 5, 6, 8 ]
(1, 8) [ 1, 2, 3, 5, 6, 8 ] (7, 7) [ 7, 6, 7 ]
(1, (3,4)) [ 1, 2, 3, 4 ] (7, 8) [ 7, 6, 8 ]
(1, (3,5)) [ 1, 2, 3, 5 ] i (2, 4) [ 2, 3, 4 ]
(1, (6,7)) [ 1, 2, 3, 5, 6, 7 ] (2, (3,4)) [ 2, 3, 4 ]
(1, (6,8)) [ 1, 2, 3, 5, 6, 8 ] (2, (3,5)) [ 2, 3, 5 ]
(4, 4) [ 4, 3, 4 ]
med (5, 8) [ 5, 6, 8 ] (4, (3,4)) [ 4, 3, 4 ]
var (8, 8) No path needed (4, (3,5)) [ 4, 3, 5 ]
sd (8, 8) No path needed (5, 7) [ 5, 6, 7 ]
(5, (6,7)) [ 5, 6, 7 ]
sum (1, 4) [ 1, 2, 3, 4 ] (5, (6,8)) [ 5, 6, 8 ]
(1, 5) [ 1, 2, 3, 5 ] (7, 7) [ 7, 6, 7 ]
(4, 4) [ 4, 3, 4 ] (7, (6,7)) [ 7, 6, 7 ]
(4, 5) [ 4, 3, 5 ] (7, (6,8)) [ 7, 6, 8 ]
DU Paths for Stats – No Duplicates
There are 38 DU paths for Stats, but only 12 unique
[ 1, 2, 3, 4 ] [ 4, 3, 4 ]
[ 1, 2, 3, 5 ] [ 4, 3, 5 ]
[ 1, 2, 3, 5, 6, 7 ] [ 5, 6, 7 ]
[ 1, 2, 3, 5, 6, 8 ] [ 5, 6, 8 ]
[ 2, 3, 4 ] [ 7, 6, 7 ]
[ 2, 3, 5 ] [ 7, 6, 8 ]
4 expect a loop not to be “entered”
6 require at least one iteration of a loop
2 require at least two iterations of a loop
Test Cases and Test Paths
Test Case : numbers = (44) ; length = 1
Test Path : [ 1, 2, 3, 4, 3, 5, 6, 7, 6, 8 ]
Additional DU Paths covered (no sidetrips)
[ 1, 2, 3, 4 ] [ 2, 3, 4 ] [ 4, 3, 5 ] [ 5, 6, 7 ] [ 7, 6, 8 ]
The five stars that require at least one iteration of a loop
Test Case : numbers = (2, 10, 15) ; length = 3
Test Path : [ 1, 2, 3, 4, 3, 4, 3, 4, 3, 5, 6, 7, 6, 7, 6, 7, 6, 8 ]
DU Paths covered (no sidetrips)
[ 4, 3, 4 ] [ 7, 6, 7 ]
The two stars that require at least two iterations of a loop
Other DU paths require arrays with length 0 to skip loops
But the method fails with index out of bounds exception…
med = numbers [length / 2]; A fault was
found
Summary
• Applying the graph test criteria to control flow graphs is relatively
straightforward
• Most of the developmental research work was done with CFGs
• A few subtle decisions must be made to translate control structures
into the graph
• Some tools will assign each statement to a unique node
• These slides and the book uses basic blocks
• Coverage is the same, although the bookkeeping will differ