Data Flow P-Slice Testing (chapter 9)

advertisement
Data Flow Testing
• Data flow testing(DFT) is NOT directly related to the
design diagrams of data-flow-diagrams(DFD).
• It is a form of structural testing and a White Box
testing technique that focuses on program variables
and the paths:
– From the point where a variable, v, is defined or assigned a
value
– To the point where that variable, v, is used
Remember, to generate the path for testing we need to set up the
data to drive the path.
Static Analysis of Data
• Static analysis allows us to check (test or find faults) without
running the actual code, and we can apply it to analyzing
variables as follows:
1. A variable that is defined but never used
2. A variable that is used but never defined
3. A variable that is defined a multiple times prior to usage.
•
While these are dangerous signs, they may or may not lead to
defects.
1. A defined, but never used variable may just be extra stuff
2. Some compilers will assign an initial value of zero or blank to all
undefined variable based on the data type.
3. Multiple definitions prior to usage may just be bad and wasteful
logic
•
We are more interested in “executing” the code than
just static analysis, though.
Variable Define-Use Testing
• In define-use testing, we are interested in
testing (executing) certain paths that a
variable is defined – to - its usage.
• These paths will provide further information
that will allow us to decide on choice of test
cases beyond just the earlier discussed
paths analysis (all statements testing or ddtesting (branch) or linearly independent
paths).
Data Dependencies and Data Flow
Testing(DFT)
• In Data Flow Testing (DFT) we are interested in the
“dependencies” among data or “relationships”
among data ----- Consider a data item, X:
– Data Definitions (value assignment) of X: via 1) initialization,
2) input, or 3) some assignment.
• Integer X; (compiler initializes X to 0 or it will be “trash”)
• X = 3;
• Input X;
– Data Usage (accessing the value) of X: for 1) computation
and assignment (C-Use) or 2) for decision making in a
predicate (P-Use)
• Z = X + 25; (C-Use)
• If ( X > 0 ) then ----- (P-Use)
Some Definitions
• Defining node, DEF(v,n), is a node, n, in the program graph where
the specific variable, v, is defined or given its value (value
assignment).
• Usage node, USE(v,n), is a node, n, in the program graph where
the specific variable, v, is used.
• A P-use node is a usage node where the variable, v, is used as a
predicate (or for a branch-decision-making).
• A C-use node is any usage node that is not P-used.
• A Definition-Use path, du-path, for a specific variable, v, is a
path where DEF(v,x) and USE(v,y) are the initial and the end
nodes (x and y nodes) of that path.
• A Definition-Clear path for a specific variable, v, is a DefinitionUse path with DEF(v,x) and USE(v,y) such that there is no other
node in the path that is a defining node of variable, v. (e.g. v
does not get reassigned in the path. )
Simple Example
3
1. Pseudo-code Sample
This is type defining not value
2. int a, b
3. input (a, b)
4. if (a > b)
5.
then Output (a, “ a bigger than b”)
6.
else Output (b, “ b is equal or greater than a”)
7. end
4
6
5
7
The following are examples of the definitions:
• DEF(a, 3) – node 3 is a defining node of variable “a” --- a value is assigned to “a”
• USE(a, 4) – node 4 is a usage node of variable “a”
• USE(a, 5) – node 5 is a usage node of variable “a”
• USE (a,4) is a P-use node while
• USE(a,5) is C-use node
• Path that begins with DEF(a,3) and ends with USE(a,4) is a definition-use path of a
• Path that begins with DEF(a,3) and ends with USE(a,5) is a definition-use path of a
• Path that begins with DEF(a,3) and ends with USE(a,5) is a definition-clear path of a
• Path that begins with DEF(b,3) and ends with USE(b.6) is a definition-use path of b
Note that: if we choose the definition-use paths [last two examples above] of both
variables a and b, then it is the same as executing the decision-decision (dd) path
or branch testing.
“Commission Program” Partial Example from Text :
on variable “locks”
(using statement number instead of “node”)
other assignments
13. Input (locks)
false
14. While NOT
(locks equals -1)
true
15. Input( stocks, barrels)
16. Totallocks= Totallocks + locks
17. Totalstocks =Totalstocks + stocks
18. Totalbarrels = Totalbarrels + barrels
19. Input (locks)
20. EndWhile
21. Output (“Locks sold “ , Totallocks)
continuing other statements
• we have DEF(locks,13) and DEF(locks,19)
• we have USE(locks,14) and USE(locks,16)
• We can employ the define/use methodology
and get the following paths:
- path1 = DEF(locks,13) to USE(locks,14)
- path2 = DEF(locks,13) to USE(locks,16)
- path3 = DEF(locks,19) to USE(locks14)
- path4 = DEF(locks,19) to USE(locks,16)
•But we have not even tested all the branches!
• Modify Path1 to include nodes <13,14,21> and
call it Path1’
• Also modify Path3 to include nodes
<19,’20’,14, 21> and call it Path3’
With Path1’, Path2, Path3’ and Path4, we have
covered all 4 cases:
1) Path1’ = by-pass loop,
2) Path2 = drop Into loop,
3) Path3’ = exit loop, and
4) Path4 = repeat the loop
Definitions/Concepts of Definition-Use (DU) Testing
•
•
•
•
•
All-Defs : contains set of test paths, P, where for every variable v in the
program, P includes definition-clear paths from every DEF(v,n) to only one of
its use node.
All-Uses: contains set of test paths, P, where for every variable v in the
program, P includes definition-clear paths from every DEF(v,n) to every use
of v and to the successor node of that use node.
All-P-Use/Some C-Use: contains set of test paths, P, where for every
variable v in the program, P contains definition-clear paths from DEF(v,n) to
every predicate –use node of v; and if there is no predicate-use, then the
definition-clear path leads to at least one C-use node of v.
All-C-Use/Some P-Use: contains set of test paths, P, where for every
variable v in the program, P contains definition-clear paths from DEF(v,n) to
every computation-use node of v; and if there is no computation-use, then
the definition-clear path leads to at least one predicate-use node of v.
All-DU-paths: contains the set of paths, P, where for every variable v in the
program, P includes definition-clear paths from every DEF(v,n) to every
USE(v,n) and to the successor node of each of the USE(v,n), and that these
paths are either single loop traversals or they are cycle free.
Summarizing hierarchy
All possible paths
All-DU-paths
All-Uses
All-C-Use/some-P-Use
All-P-Use/some-C-Use
All-Defs
Text page 160 has another chain
Under All-P-Use/some-C-Use;
take a look at that page.
Program Slices
• A concept related to dataflow analysis (def-use path) is
to look at a slice of program that is related to some
“variable of interest” and trace the program statements
that are in the program slice. (Program slice was first
discussed by Mark Weiser in the 1980’s)
– Tracing program statements that contribute or affect the value
of the variable of interest at some point of the program; { e.g.
(v,node) } going “backward” to include all those statements
that have affected the variable’s value is considered a slicing
of the program with respect to that variable.
– The designated program slice then becomes a path that one
would consider for testing.
• This is also a popular, perhaps subconscious,
debugging technique used by most of us.
A simple example of Program Slice
Pseudo code example
- Consider that our variable of interest is y
at statement 7. (and pick up statements 6 & 2)
1. int limit = 10;
2. int y = 0;
3. int x = 0;
4. for (int i = 0; i < limit ; i++)
5. { x = x + i;
6. y = y + i2 ; }
7. print (“ x = “, x , “y =“, y);
- But , on second look, we would pick up
statements:
7
6
4 (because the loop influences statement 6)
2
1 (because limit influences statement 4)
-Statements <1,2,4,6,7 > form a program slice
related to variable, y
- We would include this slice as a test case
Note that: in executing just this slice for the
value of y at statement 7 is the same
as executing the whole example
good for tracing
bug but ---- for
testing?
Definition of Program Slice
•
logical prior, may
be physically after
Given a program P and a set of variables, V, in P, a
slice on the variable set V at some statement n,
denoted at S(V,n), is a set of all statements in P, “prior
to” and at n, that contribute to the values of those
variables in V at that statement-fragment n.
(note that V can be one or more variables --- empty set V is not
considered )
–
“Contribute” is a key word that should be expanded to
consider various types of contribution ( usage and definition) :
1.
2.
3.
4.
5.
P- use (in predicate)
C- use (in computation)
O- use (in outputs)
L-use (used as pointers to locations)
I-use (used as part of some iteration counter)
1.
2.
I- def (defined through input)
A-def (defined via assignment)
More on Program Slicing
• Note that we can’t just blindly apply the
usage rules.
Note that we have modified statement 5
of the previous example to include y.
Pseudo code example
1. int limit = 10;
2. int y = 0;
3. int x = 0;
4. for (int i = 0; i < limit ; i++)
5. {x = x + i + y;
Modified to include y
6. y = y + i2 ; }
7. print (“ x = “, x , “y =“, y);
Now should S(y,7) include statement 5?
Even though this is C-use of y, statement
5 does not “contribute” to the value of y
in statement 7. So we do not include 5 in
the slice, S(y,7).
Also, p-use of other variable not in the
set V (in this case V = y) may need to be
included because it influences the value
of y. In this case, the variable, “limit,” in
the “for” statement. So, statement 4 is
included in S(y.7) as before. And limit is
placed into the set V, Variable of interest.
Program Slices with Previous Partial Example
other assignments
13. Input (locks)
false
14. While NOT
(locks = -1)
true
15. Input( stocks, barrels)
16. totallocks= totallocks + locks
17. totalstocks =totalstocks + stocks
18. Totalbarrels = totalbarrels + barrels
19. Input (locks)
20. EndWhile
21. Output (“Locks sold “ , totallocks)
continuing other statements
- For variable, locks, we can see that
- nodes 13 and 19 are input-definition nodes
- node 14 is a predicate – use node
- node 16 is a c-use node
Now let’s look at some examples
-
S (locks, 13) = < 13 >
S (locks, 14) = <13, 14, 19, 20> (may split this)
S (locks, 16) = <13, 14, 19, 20> (may split this)
S (locks, 19) = <19>
Note that statement 16 is not included in these
slices even though it is C-use of locks.
For variable, stocks:
- node 15 is the input-def node
- node 14 influences node 15
- node 13 influences node 14
- node 19 influences node 14
So, Slice(stocks,15) = <13,14,15,19,20>
Program slices
• Although program slice technique is based
on the define-use dataflow approach, we do
not need to include all the d-u paths that has
no real influencing or contribution value to
testing ( or debugging) a particular variable.
• Program slice requires more analysis, but it
allows us to focus on only those parts that
are of interest.
Remember “testability” from Whitaker’s paper? ---Perhaps, we can study testability with program slices?
Download