Lecture 4
Lecture 4
2
Defining a variable
A variable is said to be defined (created or initialized or
instantiated) in a statement if it acquires a value at that
statement.
Examples
int x; // default initialization to zero in C
lang.
int x = 0; // initialized at declaration
x = 15; // assigned a value
x = compute(y); // computed and assigned a value
obj = new MyClass(); // instantiated
public void method (int param) { // instantiated through
// parameter passing
// mechanism
3
Using a variable
A variable is said to be used in a statement if its value is
extracted and utilized in that statement.
Examples
y = x; // value of x is assigned to y
y = compute (x); // value of x is used as a parameter
if (x) { // value of x is used as a conditional attribute
sort (arr); // value of arr is used as a parameter and at the same time
it is subject to modification by the method sort.
myObject = previousObject; // two variables pointing to the
// same object but no values
// extracted or changed
anObject = clone (previousObject); // values of
// previousObject are
//copied into anObject
4
Terminating a variable
A variable is said to be terminated (or killed) when its
value is no longer accessible or relevant to the
program. Trying to access its value must result in an
exception or program crash.
Examples
public int compute (int param) {
Termination point
int result;
….
return result;
}
5
Static and Dynamic Data Flow Testing
Static Data Flow Testing
Analyze code without executing
Through control flow graphs
Identify most data flow anomalies
Dynamic Data Flow Testing
Analyze code by executing and tracing the paths
Additional code or tool support necessary
Useful to find data anomalies such as “array index out of bounds”, “divide by
zero”
6
Why to detect data flow anomalies?
Consider
x = compute(y);
x = compute(z);
Possible interpretations of the situation
The first statement is redundant
There is a mistake in the first statement; it is supposed to be
w = compute(y);
There is a mistake in the second statement; it is supposed to be
w = compute(z);
There is a missing statement in between the two that uses ‘x’;
something like
w = function(x);
7
Categories of Data Flow Anomalies
Symbols used in the following tables
d – defined
u = used
k = killed/terminated
~d – first time defined
~u – first time used
~k – first time killed
8
Categories of Data Flow Anomalies
Anomaly Explanation
~d First define Allowed
9
Categories of Data Flow Anomalies (continued)
Anomaly Explanation
ku Killed and used Serious defect; trying to
access data that was
killed
kd Killed and redefined Allowed
11
Define-use (du) path (continued)
DEF (v,n) can be further classified into
I-def (v,n) where the variable v is read from input
variable ‘n’ in factorial problem
Variables passed through parameters also belong to this category
A-def (v,n) where the variable v is assigned using an assignment
statement
variables ‘i’ and ‘ret’ in factorial problem
Such a classification helps deriving further test cases, particularly for I-def
(v,n) cases
Also useful in tracing the nature of a fault
12
Define-use (du) path (continued)
USE (v,n) can further be classified as
P-use (v,n) where v is used in a predicate
C-use (v,n) where v is used in a computation
O-use (v,n) where v is used in an output statement
L-use (v,n) where v is used in a location (pointer or
subscript)
I-use (v,n) where v is used as a loop index or an internal
counter
13
Modified program graph for the factorial example
1 ret = 0
int i, n, ret; 2
4
n<0 return ret
3
i = n; ret = 1
5
i>0
6
ret = ret * i; i = i - 1
7
8 return ret
16
Exercise
Find the du-paths of all variables for the “Compute Binary” problem.
Find the du-paths of all variables for the “Merge” method given in an
earlier exercise.
17
Observations
Data flow testing will be quite helpful
when the code is larger (several lines ) and/or deeply nested
In these scenarios, it is hard to trace the variables in the code manually
when there are several variables that are shared across many methods (e.g.,
attributes or instance variables of a class)
Local variables are somewhat easier to trace depending on the size of a method because
their scope is limited to the method
when data is frequently exchanged between the code and a database
Remember that a database may be updated externally without going through the code