0% found this document useful (0 votes)
78 views22 pages

Control and Dataflow Testing Guide

The document discusses different types of software testing: - White box testing focuses on internal program structure like control flow and data flow. Black box testing ignores internal structure and focuses on inputs and outputs. - Testing object-oriented programs involves class testing to check polymorphism and build call graphs from the class hierarchy. - Control flow testing builds a graph of the program's control structure and aims to cover nodes, edges, branches, and paths with test cases. Dataflow testing aims to cover definitions and uses of variables in the program.

Uploaded by

Pauravi Nagarkar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
78 views22 pages

Control and Dataflow Testing Guide

The document discusses different types of software testing: - White box testing focuses on internal program structure like control flow and data flow. Black box testing ignores internal structure and focuses on inputs and outputs. - Testing object-oriented programs involves class testing to check polymorphism and build call graphs from the class hierarchy. - Control flow testing builds a graph of the program's control structure and aims to cover nodes, edges, branches, and paths with test cases. Dataflow testing aims to cover definitions and uses of variables in the program.

Uploaded by

Pauravi Nagarkar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

Testing2

• White box testing


– Control-flow and dataflow metrics
– Coverage metrics
• Black box testing
• Testing OO programs
– Class testing
• Testing polymorphism
• Building call graphs using class hierarchy information

Testing2-11, CS431 F06, BG Ryder/A Rountev 1

Control-flow-based Testing

• Traditional form of white-box testing


• Step 1: From the source code, create
a graph describing the flow of control
– Called the control flow graph
– The graph is created (extracted from the
source code) manually or automatically
• Step 2: Design test cases to cover
certain elements of this graph
– Nodes, edges, branches, paths
Testing2-11, CS431 F06, BG Ryder/A Rountev 2

1
Example s:=0
d:=0
s:=0;
d:=0;
x<y?
while (x<y) {
x:=x+3; Control-flow graph
y:=y+2;
if (x+y < 100) x:=x+3;
s:=s+x+y; y:=y+2;
else
d:=d+x-y;
} T x+y<100?
s:=s+x+y

F
Testing2-11, CS431 F06, BG Ryder/A Rountev
d:=d+x-y 3

Elements of a Control Flow Graph

• Three kinds of nodes:


– Statement nodes: single-entry-single-exit
sequences of statements
– Predicate (decision) nodes: conditions for
branching
– Auxiliary nodes: (optional) for easier
understanding of conditional flow
constructs (e.g. merge points for IF)
• Edges: show possible flow of control

Testing2-11, CS431 F06, BG Ryder/A Rountev 4

2
IF-THEN, IF-THEN-ELSE, SWITCH
if (c) if (c) switch (c)
then … then … case 1: …
join point else … case 2: …
join point . . .
join point

... ... ... ...........

Testing2-11, CS431 F06, BG Ryder/A Rountev 5

switch (position) Example


case CASHIER:
if (empl_yrs > 5)
bonus := 1;
else
bonus := 0.7;
.....

break;
case MANAGER:
bonus := 1.5;
if (retiring_soon)
bonus := 1.2 * bonus
break;
case ...
endswitch
Testing2-11, CS431 F06, BG Ryder/A Rountev 6

3
Mapping for Loops

while (c) {

...
}

Note: other loops (e.g. FOR,


DO-WHILE, …) are mapped similarly

Mini-assignment: figure out how to map


these other styles of loops
Testing2-11, CS431 F06, BG Ryder/A Rountev 7

Statement Coverage

• Given the control flow graph, define a


coverage “target” and write test cases
to achieve it
• Traditional goal: statement coverage
– Find a set of tests that cover all nodes
• Hypothesis: Code that has not been
executed during testing is more likely
to contain errors
– Often this is the “low-probability” to be
executed code
Testing2-11, CS431 F06, BG Ryder/A Rountev 8

4
Example
• Suppose that we write and
execute two test cases
1
• Test case #1: follows path
1-2-exit
2 exit
• Test case #2: 1-2-3-4-5-7-
8-2-3-4-5-7-8-2-exit (loop 3
twice, and both times take
the true branch) T 4 F
• Problem: node 6 is never 5 6
executed, so we don’t have
100% statement coverage 7

8
Testing2-11, CS431 F06, BG Ryder/A Rountev 9

Branch Coverage

Goal: write tests that cover all branches


of the predicate nodes
– True and false branches of each IF
– The two branches corresponding to the
condition of a loop
– All alternatives in a SWITCH
• In modern languages, branch coverage
implies statement coverage
– Because there are no goto’s
Testing2-11, CS431 F06, BG Ryder/A Rountev 10

5
Branch Coverage

• Statement coverage does not imply


branch coverage
• Example: if (c) then s;
– By executing only with c=true, we will
achieve statement coverage, but not
branch coverage
• Motivation: experience shows that
many errors occur in “decision making”
– Plus, it subsumes statement coverage
Testing2-11, CS431 F06, BG Ryder/A Rountev 11

Example
• Same example as
1
before: two test cases
– Path 1-2-exit 2
– Path 1-2-3-4-5-7-8-
2-3-4-5-7-8-2-exit 3
• Problem: the “false”
branch of 4 is never T 4 F
taken - don’t have 5 6
100% branch coverage 7

8
Testing2-11, CS431 F06, BG Ryder/A Rountev 12

6
Achieving Branch Coverage

• Branch coverage: a necessary minimum


– Pick a set of start-to-end paths that cover all
branches, and write tests cases to execute these
paths
• Basic strategy
– Add a new path that covers at least one edge
that is not covered by the current paths
– Sometimes the set of paths chosen with this
strategy is called the “basis set”
• Cf PRE Ch 14.4.2

Testing2-11, CS431 F06, BG Ryder/A Rountev 13

Testing Loops
• Simple loops
• Skip loop entirely
• Go once through the loop
• Go twice through the loop
• If loop has max passes=n, then go n-1,n, n+1
times through the loop
• Nested loops
• Set all outer loops to their minimal value and
test innermost loop
• Add tests of out-of-range values
• Work outward, at each stage holding all outer
loops at their minimal value
• Continue until all loops are tested
Testing2-11, CS431 F06, BG Ryder/A Rountev 14

7
Dataflow-based Testing
• Test connections between variable
definitions (“write”) and variable uses
(“read”)
• Variation of the control flow graph
– A node represents a single statement, not
a single-entry-single-exit chain of
statements
• Set DEF(n) contains variables that are
defined (written) at node n
• Set USE(n): variables that are read
Testing2-11, CS431 F06, BG Ryder/A Rountev 15

Example
assume y is already initialized
1 2 3
1 s:=0;
DEF(1)={s} USE(1)=∅
2 x:=0; 4
DEF(2)={x} USE(2)=∅
3 while (x<y) {
DEF(3)=∅ USE(3)={x,y}
4 x:=x+3; 5
DEF(4)={x} USE(4)={x}
5 y:=y+2;
6 if (x+y<10) DEF(5)={y} USE(5)={y} 6
7 s:=s+x+y; DEF(6)=∅ USE(6)={x,y}
else DEF(7)={s} USE(7)={s,x,y} 7 8
8 s:=s+x-y; DEF(8)={s} USE(8)={s,x,y} 9
} DEF(9)=∅ USE(9)=∅
DEF(10)=∅ USE(10)=∅
Testing2-11, CS431 F06, BG Ryder/A Rountev
10 16

8
Reaching Definitions
A definition of x at n1
reaches n2 if and only if 1 2 3
there is a path between n1
and n2 that does not 4
contain a definition of x 5
DEF(1)={s} USE(1)=∅
Reaches DEF(2)={x} USE(2)=∅
6
DEF(3)=∅ USE(3)={x,y}
nodes 2, 3, DEF(4)={x} USE(4)={x} 7 8
4, 5, 6, 7, DEF(5)={y} USE(5)={y}
DEF(6)=∅ USE(6)={x,y} 9
8, but not
DEF(7)={s} USE(7)={s,x,y}
9, 10 DEF(8)={s} USE(8)={s,x,y}
Testing2-11, CS431 F06, BG Ryder/A Rountev 10 17

Def-Use Pairs

• A def-use (DU) pair for variable x is a


pair of nodes (n1,n2) such that
– x is in DEF(n1)
– the definition of x at n1 reaches n2
– x is in USE(n2)
• The value that is assigned to x at n1 is
used at n2
– Since the definition reaches n2, along
some path n1…n2 the value is not “killed”
Testing2-11, CS431 F06, BG Ryder/A Rountev 18

9
Example of Def-Use Pairs
Reaches nodes 2, 3, 4, 5,
6, 7, 8, but not 9, 10 1 2 3

For defn 4
of s at 1,
two DU 5
DEF(1)={s} USE(1)=∅
pairs DEF(2)={x} USE(2)=∅
1-7, 6
1-7 1-8 DEF(3)=∅ USE(3)={x,y}
DEF(4)={x} USE(4)={x} 7 8
DEF(5)={y} USE(5)={y}
DEF(6)=∅ USE(6)={x,y} 9
DEF(7)={s} USE(7)={s,x,y}
DEF(8)={s}
Testing2-11, CS431 F06, BG Ryder/A Rountev
USE(8)={s,x,y} 10 19

Dataflow-based Testing

• Identify all DU pairs and construct


test cases that cover these pairs
– Variations with different “strength”
• All-DU-paths: for each DU pair
(n1,n2) for x, exercise all possible
paths n1…n2 that are clear of
definitions of x
• All-uses: for each DU pair (n1,n2) for
x, exercise at least one path n1…n2
that is clear of definitions of x
Testing2-11, CS431 F06, BG Ryder/A Rountev 20

10
Dataflow-based Testing

• All-defs: for each definition, cover at least


one DU pair for that definition
– i.e., if x is defined at n1, execute at least one
path n1…n2 such that x is in USE(n2) and the
path is clear of definitions of x
• All-defs <<(subsumes) all-uses << all DU-paths
• Motivation: see the effects of using the
values produced by computations
– Focuses on the data, while control-flow-based
testing focuses on the control

Testing2-11, CS431 F06, BG Ryder/A Rountev 21

Dataflow-based Testing

• Best criteria (?): all-paths


– Select data that traverses all paths in a
program, but possible problems:
• Data causing execution to traverse a path, may not
reveal an error on that path
• There may be an infinite number of paths due to loops
• Rapps & Weyuker 1985 contribution
– Designed a family of test data selection criteria
so finite number of paths traversed
– Systematic exploration of satisfying the criteria
– Coverage criteria can be automatically checked
S. Rapps, E. Weyuker, “Selecting Software Test Data
Using Data Flow Information, IEEE TSE, April 1985,
Testing2-11, CS431 F06, BG Ryder/A Rountev pp 367-375. 22

11
Black-box Testing
• Unlike white-box testing: don’t use any
knowledge about the internals of the
code
• Test cases are designed based on
specifications
• Test of expected behavior
• Example: search for a value in an array
– Postcondition: return value is the index of
some occurrence of the value, or -1 if the
value does not occur in the array
Testing2-11, CS431 F06, BG Ryder/A Rountev 23

Equivalence Partitioning

• Consider input/output domains and partition


them into equivalence classes
– For different values from the same class, the
software should behave equivalently
• Test values from each class
– For input range 2..5: “less than 2”, “between 2
and 5”, and “greater than 5”
• Testing with values from different classes is
more likely to find errors than testing with
values from the same class

Testing2-11, CS431 F06, BG Ryder/A Rountev 24

12
Equivalence Classes

• Examples
– Input x in range [a..b]: three classes
“x<a”, “a<=x<=b”, “b<x”
– Boolean: classes true and false
– Some classes may represent invalid input
• Choosing test values
– Choose a typical value in the middle of the
class(es) that represent valid input
– Choose values at the boundaries of classes
• e.g. for [a..b], use a-1, a, a+1, b-1, b, b+1

Testing2-11, CS431 F06, BG Ryder/A Rountev 25

Example

• Spec says that the code accepts between 4


and 24 inputs; each is a 3-digit integer
• One partition: number of inputs
– Classes “x<4”, “4<=x<=24”, “24<x”
– Chosen values: 3,4,5,14,23,24,25
• Another partition: integer values
– Classes: “x<100”, “100<=x<=999”, “999<x”
– Chosen values: 99,100,101,500,998,999,1000

Testing2-11, CS431 F06, BG Ryder/A Rountev 26

13
Another Example

• Similarly for the output: exercise


boundary values
• Spec: the output is between 3 and 6
integers, each in the range 1000-2500
• Try to design inputs that produce
– 3 outputs with value 1000
– 3 outputs with value 2500
– 6 outputs with value 1000
– 6 outputs with value 2500

Testing2-11, CS431 F06, BG Ryder/A Rountev 27

Example: Searching

• Search for a value in an array


– Return: index of some occurrence of the value, or
-1 if the value does not occur
• One partition: size of the array
– Programmer errors are often made for size 1: a
separate equivalence class
– Classes: “empty array”, “array with one element”,
“array with many elements”
• Another partition: location of the value
– “first element”, “last element”, “middle element”,
“not found”

Testing2-11, CS431 F06, BG Ryder/A Rountev 28

14
Example: Searching
Array Value Output
empty 5 -1
[7] 7 0
[7] 2 -1
[1,6,4,7,2] 1 0
[1,6,4,7,2] 4 2
[1,6,4,7,2] 2 4
[1,6,4,7,2] 3 -1
Testing2-11, CS431 F06, BG Ryder/A Rountev 29

Object-Oriented Software

• Initially hoped it would be easier to


test OO software than procedural
software
– Soon became clear that this is not true
• Some of the older testing techniques
are still useful
• New testing techniques are designed
specifically for OO software

Testing2-11, CS431 F06, BG Ryder/A Rountev 30

15
One Difference: Unit Testing

• Traditional view of “unit”: a procedure


• In OO: a method is similar to a procedure
• But a method is part of a class, and is
tightly coupled with other methods and fields
in the class
• The smallest testable unit is a class
– It doesn’t make sense to test a method as a
separate entity
• Unit testing in OO = class testing

Testing2-11, CS431 F06, BG Ryder/A Rountev 31

Class Testing

• Traditional black-box and white-box


techniques still apply
– E.g. testing with boundary values
– Inside each method:
• Obtain at least 100% branch coverage;
• Cover all DU-pairs inside a method (intra-
method)
– DU pairs that cross method boundaries
(inter-method)
• Example: inside method m1, field f is assigned
a value; inside method m2, this value is read
Testing2-11, CS431 F06, BG Ryder/A Rountev 32

16
Example: Inter-method DU Pairs
class A {
private int index;
public void m1() {
index = …;

m2();
}
private void m2() { … x = index; … }
public void m3() { … z = index; … }
}
test 1: call m1, which writes index and then
calls m2 which reads the value of index
test 2: call m1, and then call m3

Testing2-11, CS431 F06, BG Ryder/A Rountev 33

Possible Test Suite


public class MainDriver {
public static void main(String[] args) {
A a = new A();

a.m1();
a.m3();

}

Note: need to ensure that the actual execution


exercises definition-free paths for each of the
two DU pairs
Testing2-11, CS431 F06, BG Ryder/A Rountev 34

17
Class Testing

• Also try to test all sequences of calls


to public methods of A, that a client
of A could invoke (intra-class)
• Want to discover more DU edges to test, that
can be setup by this sort of sequence of calls
• Q: What about overriding subclass
methods? How do they get tested?

Testing2-11, CS431 F06, BG Ryder/A Rountev 35

Polymorphism

• Example: class A with subclasses B and C


– class A { … void m() {…} …}
– class B extends A { … }
– class C extends A { … void m() {…} … }
• Suppose inside class X there is call a.m(),
where variable a is of type A
– Could potentially send message m() to an instance
of A, instance of B, or instance of C
– The invoked method could be A.m or C.m

Testing2-11, CS431 F06, BG Ryder/A Rountev 36

18
Testing of Polymorphism

• During class testing of X: “drive” call site


a.m() through all possible bindings
• All-receiver-classes: execute with at least
one receiver of class A, at least one
receiver of class B, and at least one
receiver of class C
• All-invoked-methods: need to execute with
receivers that cover A.m and C.m
– i.e. (A or B receiver) and (C receiver)
• Q: How can we figure out the possible
method targets?
Testing2-11, CS431 F06, BG Ryder/A Rountev 37

Compile-time Analysis

• Class Hierarchy Analysis (CHA)


• Use knowledge of type hierarchy to
figure out possible method targets at a
call site a.f()
• Know all subclasses of a class A, when a
declared to be an A object
• Know all methods defined in those subclasses
with same method signature f()
• Refinement: also might collect info on which
classes are actually instantiated (RTA) so don’t
over-expand call graph

Testing2-11, CS431 F06, BG Ryder/A Rountev 38

19
Example
cf Frank Tip, OOPSLA’00
static void main(){ class A {
B b1 = new B(); foo(){..}
A a1 = new A(); }
f(b1); class B extends A{ A
g(b1);
foo() {…}
}
}
static void f(A a2){
a2.foo();
class C extends B{ B
} foo() {…}
static void g(B b2){ }
B b3 = b2; class D extends B{ C D
b3 = new C(); foo(){…}
b3.foo(); }
}

Testing2-11, CS431 F06, BG Ryder/A Rountev 39

CHA Example
cf Frank Tip, OOPSLA’00

static void main(){ class A {


B b1 = new B(); foo(){..}
A a1 = new A(); }
f(b1); class B extends A{ A
g(b1); foo() {…}
} }
static void f(A a2){ class C extends B{ B
a2.foo(); foo() {…}
} }
class D extends B{
C D
foo(){…}
static void g(B b2){
}
B b3 = b2;
b3 = new C();
b3.foo();
}
Testing2-11, CS431 F06, BG Ryder/A Rountev
Cone(Declared_type(receiver)) 40

20
CHA Example
class A { All-Receiver-class coverage
static void main(){
foo(){..} requires that we cover each
B b1 = new B();
A a1 = new A(); } possible receiver type at call in f().
f(b1); class B extends A{ main
g(b1); foo() {…}
} }
static void f(A a2){ class C extends B{
a2.foo(); foo() {…}
}
} f(A) g(B)
static void g(B b2){
class D extends B{
B b3 = b2;
foo(){…}
b3 = new C();
b3.foo(); }
}

All-invoked-method coverage A.foo() B.foo() C.foo() D.foo()


requires that we cover each
outgoing edge from the call in f(). Call Graph
Testing2-11, CS431 F06, BG Ryder/A Rountev 41

RTA Example
cf Frank Tip, OOPSLA’00
static void main(){ class A {
B b1 = new B(); foo(){..}
A a1 = new A(); }
f(b1); class B extends A{ A
g(b1); foo() {…}
} }
static void f(A a2){ class C extends B{ B
a2.foo(); foo() {…}
} }
class D extends B{
C D
foo(){…}
static void g(B b2){
}
B b3 = b2;
b3 = new C();
b3.foo();
}
Testing2-11, CS431 F06, BG Ryder/A Rountev 42

21
RTA Example
static void main(){ class A {
B b1 = new B(); foo(){..}
A a1 = new A(); } main
f(b1); class B extends A{
g(b1); foo() {…}
} }
static void f(A a2){ class C extends B{
a2.foo();
foo() {…} f(A) g(B)
}
}
static void g(B b2){
class D extends B{
B b3 = b2;
b3 = new C(); foo(){…}
b3.foo(); }
}
A.foo() B.foo() C.foo() D.foo()

Call Graph
Testing2-11, CS431 F06, BG Ryder/A Rountev 43

22

You might also like