Guidelines for Testing Techniques and Test Measurement
B.8 Data Flow Testing
Introduction
Data flow testing is
a structural test technique which aims to execute subpaths from points where
each variable in a component is defined to points where it is referenced. These subpaths are known as definition-use
pairs (du-pairs). The different data
flow coverage criteria require different du-pairs and subpaths to be
executed. Test sets are generated here
to achieve 100% coverage (where possible) for each of those criteria.
Example
Consider
the data flow testing of the following component in Ada:
procedure
Solve_Quadratic(A, B, C: in Float; Is_Complex: out Boolean; R1, R2: out Float)
is
-- Is_Complex
is true if the roots are not real.
--
If the two roots are real, they are produced in R1, R2.
Discrim : Float :=
B*B - 4.0*A*C; --
1
R1, R2: Float; --
2
begin --
3
if Discrim < 0.0
then --
4
Is_Complex := true; --
5
else --
6
Is_Complex := false; --
7
end if; --
8
if not Is_Complex
then --
9
R1 := (-B +
Sqrt(Discrim))/ (2.0*A); --
10
R2 := (-B -
Sqrt(Discrim))/ (2.0*A); --
11
end if; --
12
end Solve_Quadratic; --
13
Note that the second line is not a
definition (of R1 and R2) but a declaration.
(For languages with default initialisation, it would be a definition.)
The first step is to list the variables used in the
component. These are: A, B, C, Discrim,
Is_Complex, R1 and R2.
Next, each occurrence
of a variable in the component is listed and assigned a category (definition,
predicate-use or computation-use):
|
|
category
|
|
line
|
definition
|
c-use
|
p-use
|
|
0
|
A,B,C
|
|
|
|
1
|
Discrim
|
A,B,C
|
|
|
2
|
|
|
|
|
3
|
|
|
|
|
4
|
|
|
Discrim
|
|
5
|
Is_Complex
|
|
|
|
6
|
|
|
|
|
7
|
Is_Complex
|
|
|
|
8
|
|
|
|
|
9
|
|
|
Is_Complex
|
|
10
|
R1
|
A,B,Discrim
|
|
|
11
|
R2
|
A,B,Discrim
|
|
|
12
|
|
|
|
|
13
|
|
|
|
The
next step is to identify the du-pairs and their type (c-use or p-use), by
identifying links from each entry in the definition column to each entry for
that variable in the c-use or p-use column.
Note that we cannot form any definition-use pair for R1 and R2 since
they only have a definition within the component.
|
definition-use
pair
|
variable(s)
|
|
(start line
-> end line)
|
c-use
|
p-use
|
|
0 ---> 1
|
A,B,C
|
|
|
0 ---> 10
|
A,B
|
|
|
0 ---> 11
|
A,B
|
|
|
1 ---> 4
|
|
Discrim
|
|
1 ---> 10
|
Discrim
|
|
|
1 ---> 11
|
Discrim
|
|
|
5 ---> 9
|
|
Is_Complex
|
|
7 ---> 9
|
|
Is_Complex
|
B.8.1 All-definitions
To
achieve 100% All-definitions data flow coverage at least one subpath from each
variable definition to some use of that definition (either p-use and c-use)
must be executed. The following test
set would satisfy this requirement:
|
|
All
Definitions
|
INPUTS
|
EXPECTED
OUTCOME
|
|
test case
|
variable(s)
|
du-pair
|
subpath
|
A
|
B
|
C
|
Is_Complex
|
R1
|
R2
|
|
|
1
|
A,B,C
|
0 --> 1
|
0-1
|
1
|
1
|
1
|
T
|
unass.
|
unass.
|
|
|
2
|
Discrim
|
1 --> 4
|
1-4
|
1
|
1
|
1
|
T
|
unass.
|
unass.
|
|
|
3
|
Is_Complex
|
5 --> 9
|
5- 9
|
1
|
1
|
1
|
T
|
unass.
|
unass.
|
|
|
4
|
Is_Complex
|
7 --> 9
|
7- 9
|
1
|
2
|
1
|
F
|
-1
|
-1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Note that several of the test cases
satisfy the requirement for more than one variable, this will apply to each of
the subsequent test sets as well. It
can also be seen that the same test inputs satisfy the subpath execution
criteria for several of the du-pairs (again this will apply to the subsequent
test sets as well).
B.8.2 All-c-uses
To
achieve 100% 'All-c-uses data flow coverage at least one subpath from each
variable definition to every c-use of that definition must be executed. The following test set would satisfy this
requirement:
|
|
All-c-uses
|
INPUTS
|
EXPECTED
OUTCOME
|
|
test case
|
variable(s)
|
du-pair
|
subpath
|
A
|
B
|
C
|
Is_Complex
|
R1
|
R2
|
|
|
1
|
A,B,C
|
0 --> 1
|
0-1
|
1
|
1
|
1
|
T
|
unass.
|
unass.
|
|
|
2
|
A,B
|
0 --> 10
|
0-1-4-7-9-10
|
1
|
2
|
1
|
F
|
-1
|
-1
|
|
|
3
|
A,B
|
0 --> 11
|
0-1-4-7-9-10-11
|
1
|
2
|
1
|
F
|
-1
|
-1
|
|
|
4
|
Discrim
|
1 --> 10
|
1-4-7-9-10
|
1
|
2
|
1
|
F
|
-1
|
-1
|
|
|
5
|
Discrim
|
1
--> 11
|
1-4-7-9-10-11
|
1
|
2
|
1
|
F
|
-1
|
-1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
B.8.3 All-p-uses
To
achieve 100% All-p-uses data flow coverage at least one subpath from each
variable definition to every p-use of that definition must be executed. The following test set would satisfy this
requirement:
|
|
All-p-uses
|
INPUTS
|
EXPECTED
OUTCOME
|
|
test case
|
variable(s)
|
du-pair
|
subpath
|
A
|
B
|
C
|
Is_Complex
|
R1
|
R2
|
|
1
|
Discrim
|
1 --> 4
|
1-4
|
1
|
1
|
1
|
T
|
unass.
|
unass.
|
|
2
|
Is_Complex
|
5 --> 9
|
5- 9
|
1
|
1
|
1
|
T
|
unass.
|
unass.
|
|
3
|
Is_Complex
|
7
--> 9
|
7-
9
|
1
|
2
|
1
|
F
|
-1
|
-1
|
B.8.4 All-uses
To
achieve 100% All-uses data flow coverage at least one subpath from each
variable definition to every use of that definition (both p-use and c-use) must
be executed. The following test set
would satisfy this requirement:
|
|
All-uses /
All du-paths
|
INPUTS
|
EXPECTED
OUTCOME
|
|
test case
|
variable(s)
|
d-u pair
|
subpath
|
A
|
B
|
C
|
Is_Complex
|
R1
|
R2
|
|
|
1
|
A,B,C
|
0 --> 1
|
0-1
|
1
|
1
|
1
|
T
|
unass.
|
unass.
|
|
|
2
|
A,B
|
0 --> 10
|
0-1-4-7-9-10
|
1
|
2
|
1
|
F
|
-1
|
-1
|
|
|
3
|
A,B
|
0 --> 11
|
0-1-4-7-9-10-11
|
1
|
2
|
1
|
F
|
-1
|
-1
|
|
|
4
|
Discrim
|
1 --> 4
|
1-4
|
1
|
1
|
1
|
T
|
unass.
|
unass.
|
|
|
5
|
Discrim
|
1 --> 10
|
1-4-7-9-10
|
1
|
2
|
1
|
F
|
-1
|
-1
|
|
|
6
|
Discrim
|
1 --> 11
|
1-4-7-9-10-11
|
1
|
2
|
1
|
F
|
-1
|
-1
|
|
|
7
|
Is_Complex
|
5 --> 9
|
5- 9
|
1
|
1
|
1
|
T
|
unass.
|
unass.
|
|
|
8
|
Is_Complex
|
7
--> 9
|
7-
9
|
1
|
2
|
1
|
F
|
-1
|
-1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
B.8.5 All-du-paths
To
achieve 100% All-du-paths data flow coverage every 'simple subpath' from each
variable definition to every use of that definition must be executed. This differs from All-uses in that every simple subpath between the
du-pairs must be executed. There are
just two subpaths through the component that are not already identified in the
test cases for All-Uses. These are 0‑1‑4‑5‑9‑10
and 1-4-5-9-10. Both of these subpaths
are infeasible and so no test cases can be generated to exercise them.
This form of testing needs to define
the data objects considered. Tools will typically regard an array or record as
a single data item rather than as a composite item with many constituents.
Ignoring the constituents of composite objects reduces the effectiveness of
data flow testing.