Data Flow Testing
Data Flow Testing
Data flow testing strategies are useful for selecting test paths of a
program containing nested if and loop statements. To illustrate
this, consider the application of DU testing to select test paths for
the PDL that follows:
3
Aug 25,
Introduction 05
Product Development:
- Ineffective: organization focus on cost.
- Effective: make the process efficient
Define Quality:
- is conformance to request.
- is fitness for intended users.
-
4
The Evolution of Quality
1. Quality Control:
- Quality Control is defined as a set of procedures designed to ensure that quality
standards and processes are adhered to, and that the final product meets or exceeds
the required technical and performance requirements, so it keeps quality at an
acceptable level by rejecting unacceptable.
- Prevent unacceptable products from being released to the customer.
- Problems:
o Not reduce defect. Fail
o Not improve process
o Not better product Request Development PC Inspection Pass
o Not motivate improvement
2. Quality Assurance:
- Covers all activities from design, development, production, installation, servicing and
documentation, this introduced the rules: "fit for purpose" and "do it right the first
time".
- Providing evidence that the quality function is being performed adequate.
- IEEE: A planned and systematic pattern of all actions necessary to provide adequate
confidence that the product conforms to established technical requirement.
- System of methods and procedures used to assure that the software product meet.
- Pros:
o More effective than quality because emphasize on development processing.
o Fix problems during and before development process
o Improve process reduce defect in a last manner
- Cos
Standard of Quality
o Separate from other process improve and software development activity.
o Motivation to improve is inconsistent
o Cost of making people monitors others.
3. Quality Engineering:
- Similar to Quality Assurance, but responsibility on everyone.
- Problems result in process change, not punishment of people.
- Finding error is good keeping them leak to customers.
- Appreciates that a competitive process is the way to remain a competitive.
- Measurement are used so decisions based on face (in addition to institution)
- Pride in quality
- Build quality in product through development
- Less adversarial
- Motivation
- Flexible to change the process in response to a problem
o Understand the problem & cause & process
- Knowledge is the foundation of successfully quality engineering.
5
A Perspective on Testing
Definition:
The process of executing a program with the intend of finding errors.
Testing Objective:
- To improve quality by finding error.
- To provide confidence in the dependability of software.
Related Terms:
- Error: A measure of the difference between the
actual and the ideal. It occurs in some hardware or Fault, Failure, and Error: (Scenario)
software component.
- Fault: A condition that causes a system to fail in Consider for instance a system running on a
performing its required function. Fault is a multi-processor architecture: a fault in one
manifestation of an error. processor might cause it to crash (i.e., a
- Failure: The inability of a system or component to failure), which will be seen as a fault of the
system. Therefore, the ability of the system
perform a required function according to its
to function even in the presence of the failure
specifications. Failure is a departure of a system
of one processor will be regarded as fault-
from the service required.
tolerance instead of failure-tolerance. (Not all
faults cause immediate failure.)
Static vs. Dynamic:
- Static Analysis is analysis done on source code
without actually executing it.
o Defects like dead-code (i.e., unreachable code) can only be detected through
careful inspection.
o Similarly, non-conformance to organization-wide coding conventions can also
be detected through inspection process only.
o Syntax errors are caught by static analysis
- Dynamic Analysis is analysis done as a program is executing and is based on
intermediate values that result from the programs execution.
o E.g., A division by 0 error is caught by dynamic analysis.
Verification:
o Are we building the right product?
o Does the software fulfill its requirement?
- Validation:
o Are we building the product right?
o Is implementing consistent with its specification?
6
A Perspective on Testing (Cont.)
Test Cases:
- Valuable (as much as source program)
- The information need to be in a test case:
o Input: Test Case ID
Preconditions
The actual inputs. Purpose
o Expected Output:
Postconditions Preconditions
Actual outputs.
o Optional: Inputs
ID
Purpose Expected Outputs
Execution history
- Testing Oracles: A testing oracle is any program, process, Postconditions
or body of data that specifies the expected outcome of a
set of tests. Oracles are often defined as a set of Execution History
input/expected outcome pairs. Date Result Version Run By
Specification
(expected) 5 Program
2 6
(observed)
1
4 3
7
Test Cases
(verified)
- Region 2 and 5: There may be specified behaviors that are not tested.
- Region 1 and 4: Specified behaviors that are tested.
- Region 3 and 7: Test cases that correspond to unspecified behaviors.
- Region 2 and 6: There may be programmed behaviors that are not tested.
- Region 1 and 3: Programmed behaviors that are tested.
- Region 4 and 7: Test cases that correspond to unprogrammed behaviors.
- Note: We need to make the region where these sets all intersect (Region 1) as large
as possible.
7
A Perspective on Testing (Cont.)
Testing strategy:
- Unit Testing: A unit is the smallest testable piece of software
(e.g., function).
- Component Testing: A component is an integrated aggregate
of one or more units (e.g., module).
- Integration Testing: This testing is used to demonstrate that
a combination of successfully tested components has bugs.
- System Testing: A system is a very large component.
System testing includes testing for:
Integration
System
Testing
o performance
Testing
o security
o system recovery from failure
Component
Testing
Concept map of testing:
Testing
Unit
Tester
Test implementation
of execution
Test case
Requirement
generation
8
Testing Techniques
Input Output
9
Sep 1, 05
1. Testing Techniques: Functional Testing
10
11
Single Fault Assumption vs. Multi Fault Assumption:
- Single Fault Assumption: specifies that exactly one component is malfunctioning and
the cause of the problem.
- Multi Faults Assumption: more than one component are causing of the problem.
12
1.1 Functional Testing: Boundary Value Testing
2. Robustness Testing:
- An extension of BVA: include value below the minimum and above the maximum
values.
o Negative Testing: how does the program handle errors in input?
o May not be possible with some strongly by typed languages, such as compiler.
- In addition to the five values of variable, exceed the extremes with maximum and
minimum.
- Useful for exception handling to test behavior for invalid input values.
- Stress input boundary. Variable
- Acceptable response for invalid input? values
- Leads to exploratory testing (test hackers)
- Discover hidden functionality. Robustness test cases (one variable)
3. Worst-Case Testing: V2
- Do not consider single fault assumption.
- Explore situation with > 1 variables in their extreme values.
- More through; useful for critical software.
- Number of test cases is 5n.
Thought on BVA:
- Does not require much thought.
- Usually assumes the variables are independent. Variables relationships not
considered.
- Values at certain boundaries may not have a meaning.
13
Boundary Value Test Cases for ('Triangle' Problem)
Test Cases:
- Worst Case:
14
Test Cases:
- Worst-Case:
Leap Year:
In the Gregorian calendar, a normal year consists of 365 days. Because the
actual length of a sidereal year (the time required for the Earth to revolve
once about the Sun) is actually 365.25635 days, a "leap year" of 366 days is
used once every four years to eliminate the error caused by three normal
(but short) years.
1) Any year that is evenly divisible by 4 is a leap year: for example, 1988,
1992, and 1996 are leap years. However, there is still a small error that must
be accounted for. To eliminate this error, the Gregorian calendar stipulates
that
2) a year that is evenly divisible by 100 (for example, 1900) is a leap year
only if it is also evenly divisible by 400. For this reason, the following years
ARE NOT leap years
1700, 1800, 1900, 2100, 2200, 2300, 2500, 2600 because they are evenly
divisible by 100 but NOT by 400. The following years ARE leap years
1600, 2000, 2400 because they are evenly divisible by both 100 and 400.
-
15
Boundary Value Test Cases for ('Commission' Problem)
Test Cases:
- Output BVA:
16
Sep 8, 05
1.2 Functional Testing: Equivalence Class Partitioning
Introduction:
- Two motivations:
o A sense of complete testing.
o Avoid redundancies.
- Several variation:
o Robust: consider invalid input.
o Weak: single fault assumption.
- Partition a set of values into a collection of mutually disjoint subsets (union is the
entire set).
o Completeness
o Disjointedness ensures a form of non-redundancy.
- Testing idea: identify test cases by using one element from each set.
- An Example: In triangle problem: {<1}, {1 200}, and {>200}
- Key idea in EC Testing:
o Wise selection of equivalent classes.
o Assuming f(X1, X2) where:
aX1d, with intervals [a,b), [b,c), [c,d]
cX2g, with intervals [e,f), [f,g]
Invalid values of X1, X2 are: X1< a, X2>d, X2<e, X2>g
17
Equivalence Class Test Cases for ('Mortgage Company' Problem)
Problem Description:
- Writes mortgage for people with monthly income of $1,000/month to $30,000/month.
- Writes a single mortgage for 1-4 homes
- Makes mortgages on condos, town houses, singled dwelling (not on duplex, mobile
home).
- Will make mortgage only for a person (not to corporations, trust, partnership)
Conditions:
- If an input represents a continuous range of values Select one valid & two invalid
classes.
# of houses
-1 0 1 2 3 4 5 6
- If input conditions is specified as a set of valid values Select one valid EC (continue
all valid members) & one invalid EC.
Valid
Single mortgage Invalid
Town houses Duplex
Condo
- If an input specifies a "must be" condition Select one invalid EC (representing the
"must be" condition) & one invalid class that does not include the "must be"
condition.
Invalid
Corporations Valid
Partnership Person
Trust
18
Equivalence Class Test Cases for ('Triangle' Problem)
Test Cases:
19
Equivalence Class Test Cases for ('NextDay' Problem) Version 1
- Valid Classes:
- Invalid Classes:
Test Cases:
20
Equivalence Class Test Cases for ('NextDay' Problem) Version 2
Test Cases:
- Weak Normal EC:
21
Equivalence Class Test Cases for (Commission' Problem) Version 1
- Valid Classes:
- Invalid Classes:
Test Cases:
22
Equivalence Class Test Cases for (Commission' Problem) Version 2
23
Sep 15,
1.3 Functional Testing: Decision Tables 05
Introduction:
- Useful for capturing and presenting complex logical decision making.
- Prototype:
Rules
(IF) Conditions
(THEN) Actions
- Example:
R8 R7 R6 R5 R4 R3 R2 R1
T T T T F F F F Valid Size:
T T F F T T F F Valid quantity
T F T F F F T F Sufficient
Funds
Yes No No No No No No No Buy
24
Decision Tables Test Cases for ('Triangle' Problem)
The Rules:
c1: a,b,c form a triangle (NEEDS to be expanded)
c1: a<b+c?
c2: b<a+c?
c3: c<a+b?
c4: a=b?
c5: a=c?
c6: b=c?
a1: not a triangle
a2: scalene
a3: isosceles
a4: equilateral
a5: impossible
Decision Table:
R1 R1 R9 R8 R7 R6 R5 R4 R3 R2 R1
1 0
T T T T T T T T T T F C1
T T T T T T T T T F - C2
T T T T T T T T F - - C3
F F F F T T T T - - - C4
F F T T F F T T - - - C5
F T F T F T F T - - - C6
x x x A1
x A2
x x x A3
x A4
x x x A5
25
Decision Tables Test Cases for ('NextDay' Problem) Version 1
The Rules:
M1 = {mon | mon has 30 days}
M2 = {mon | mon has 31 days}
M3 = {mon | mon is Feb}
D1 = {day | 1 <= day <= 28}
D2 = {day | day = 29}
D3 = {day | day = 30}
D4 = {day | day = 31}
Y1 = {year | year = 2000}
Y2 = {year | a leap year}
Y3 = {year | a common year}
Decision Table:
26
Decision Tables Test Cases for
('NextDay' Problem) Problem: Rule 8 has unknown Version 2
decision
The Rules:
M1 = {mon | mon has 30 days}
M2 = {mon | mon has 31 days; not Dec}
M3 = {mon | mon is Dec}
M4 = {mon | mon is Feb}
D1 = {day | 1 <= day <= 27}
D2 = {day | day = 28}
D3 = {day | day = 29}
D4 = {day | day = 30}
D5 = {day | day = 31}
Y1 = {year | year is a leap year}
Y2 = {year | year is a common year}
Decision Table:
Test Cases:
27
Sep 22,
Retrospective of Functional Tests 05
Effort:
- Domain-based techniques have no recognition of data or logical dependencies
- The equivalent class techniques pay attention to data dependencies and to the
function itself
- The decision table techniques requires consider both data and logical dependencies
- Trade-off between test identification effort and test execution effort
Efficiency:
- The intuitive notion is that a set of test cases is just right (no gap , no redundancy)
- The gap is the possibility of untested functionality.
Effectiveness:
- Mandate a method, use it to generate test cases, and then run the test cases
- Know how effective a set of test cases is for finding faults present in a program
28
A Brief Review of Graphs
Introduction:
- Directed graph G(V,E)
o Finite set V={n1, n2, , nm} of nodes.
o Finite set E={e1, e2, , ep} of nodes.
o Where each Ek={ni, nj} is an ordered pair
o (start node, terminal node)
- For example:
V={n1, n2, n3, n4},
E= {e1, e2, e3}={(n1,n2), (n2,n4), (n1,n3)}
e2
e1 n2 n4
n1
e3
n3
- Nodes of degrees
o Indeg (ni) = number of distinct edges that have ni as their terminal node.
o Outdeg (ni) = number of distinct edges that have ni as their start node.
o Src node : a node with indeg = 0
o Sink node: a node with outdeg = 0
o Transfer node: a node with (indeg != 0 & outdeg != 0).
- Directed path:
o a sequence of edges such that for any adjacent pairs of ei, ej, the terminal
node of ei is the start node of ej
- Connectness: for two nodes ni, nj :
o 0-connected: iff there is no path between ni & nj
o 2-connected: iff there is a path between ni & nj
o 3-connected: iff there is a path between ni to nj or and a path between nj to ni.
- Strongly connected graph:
o all pairs of nodes are 3-connected.
- Program graphs:
o Given a pgm in an imperative language, its graph is a directed graph in which
nodes are entire statements or fragment of statements and edges represent
flow of control.
29
A Brief Review of Graphs (Cont.)
Case
Sequence
Until (do/while)
While
30
n1
n2
n3
- Areas bound by edges are called a region. You will see example later.
- For compound conditions in a pgm, a separate node is created for each condition, so
if (c1 and c2) needs to be divided to two conditions if (c1) and if (c2). For example:
(Look at handout 8).
31
A Brief Review of Graphs (Cont.)
- Formula:
V(G) = #edges - #nodes +2
Example:
F
A
G
D 20 times
return
C X
H
E
I
32
Quiz on Graphs
1. Draw a flow graph for the following code segment. For simplicity, assume that P1, P2, P3
are simple predicates:
S1;
if (P1) {
for (i = 1; P2; i++) {
if(P3)
S2;
}
If (P3) S3;
} else
S4;
S5;
33
2. Testing Techniques: Structural Testing
Introduction:
- Complements functional testing.
- Based on implementation
- Powerful mathematical foundations
3. Petri nets
A Petri net is a bipartite directed graph (P, T, In,
Out), in which P and T are disjoint sets of nodes, and In
In P T
and Out are sets of edges, where , and
Out T P
. Petri nets can do what FSM does, but not the other way round
(such as parallelism).
34
2.1 Structural Testing: Control Flow-Based Testing
int *p = NULL;
if (cond) p=&v;
*p = 100;
- Without a test case to force a false evaluation, the code is considered covered.
- Also, does not report whether loops reach termination condition; only whether the loop
body is executed.
- Statement coverage is blind to other classes of errors:
if (cond)
x=1;
if (x+y>=0) // should be (y>0)
...
if (a==0)
...
if (b>3) // should be (a+b>3)
...
3. Self-blindness: conditional covers ups the error. For example, we choose x=0 to
check the following statement:
35
Sep 29,
2. Branch Coverage: 05
Subsumption Definition:
36
Example on Statement Converge and Branch Converge ('Count' Program)
(Dependable Software Systems (Path Testing) @ Spiros Mancoridis)
/* COUNT
This program counts the number of characters and lines in a text file.
INPUT: Text File
OUTPUT: Number of characters and number of lines.
*/
1 8 11 14 17 19 22 23 24 26 29
37
Example on Statement Converge and Branch Converge (Cont.)
a b c d e f g h i j k l INPUT OUTPUT
agc Invalid
Input Filename
Error Message
aghdjkli Input
File with one character and no Carriage
Number
Return
of characters
at the end =
of1the lin
Number of lines = 0
8 14 19 22 INPUT OUTPUT
aghdjkli Input
F FileFwith T,F
one character
F and no Carriage Return
Numberatof
the
characters
end of the
= line
1
Number of lines = 0
aghdefli F F Input
T,F
file with
T no characters and one
Number
carriage
ofreturn
characters = 0
Number of lines = 1
38
3. Condition Coverage:
x<y
T
x>2
T
a=0 a++
b=0 b++
39
Example on Statement Converge, Branch Converge, and Condition
Converge
Programming Code:
if (a > 3)
x++;
if (b==3)
y=0;
Flowgraph:
x++
b=3 T
y=0
Test Cases:
40
5. Multi-Condition Coverage:
if (a && b)
X();
else
Y();
1 2
Condition Branch
Coverage3 Coverage
1. Condition Coverage:
if (True && False) Y();
if (False && True ) Y();
2. Branch Coverage:
if (True && True ) X();
if (False && True ) Y();
3. Branch / Condition Coverage:
if (True && True ) X();
if (False && False) Y();
4. Multi-conditions Coverage:
if (True && True ) X();
if (True && False) Y();
if (False && True ) Y();
if (False && False) Y();
41
Example on Condition Converge and Multi-Condition Converge
Programming Code:
Flowgraph:
a>0
T
c=1
T
x++
y=0
Test Cases:
1. Condition Coverage: Test the True and False condition of each expression.
Values Test
Statement
d c b a Case
s
#
x++; y=0; -1 True 1 True 3 True 1 True 1
42
Example on Path Converge ('Average' Program)
/* AVERAGE
This procedure computes the average of 100 or fewer numbers that lie
between bounding values; it also computes the sum and the total number
valid.
*/
PROCEDURE average;
F IV
10
F
I 12 V 11
II 13
VI 1
F T
III
2
F
3
4
T
5
8 7
6 Regions
Predicate
INTERFACE RETURNS average, total.input, total.valid;
INTERFACE ACCEPTS value, minimum, maximum;
TYPE value[l:100] IS SCALAR ARRAY;
TYPE average, total.input, total.valid, minimum, maximum, sum IS SCALAR;
TYPE i IS INTEGER;
i = 1;
1 total.input = total.valid = 0;
sum = 0;
2 3
DO WHILE value[i]<>-999 AND total.input<100
4 increment total.input by 1
5 6
IF value[i]>=minimum AND value[i]<=maximum
THEN increment total.valid by 1;
7 sum = s sum + value[i]
ELSE skip
8 ENDIF
increment i by 1:
9 ENDDO
10
43
12
IF total.valid>0
11 THEN average=sum / total.valid;
1 ELSE average =-999;
13 ENDIF
END average
44
Example on Path Converge ('TotalPrice' Program)
1 rushcharge = 0 1
1 if nextday = 'Y' T
2 rushcharge = 14.50 2
3 endif 3
3 tax = amount * 0.08 T
3 if amount >= 1000
4 shipcharge = amount * .06 + rushcharge 5 4
T
5 else if amount >= 200
6 shipcharge = amount * .08 + rushcharge 7 6
7 else if amount >= 100 T
8 shipcharge = 10 + rushcharge 9 8
9 else if amount >= 50 T
10 shipcharge = 9 + rushcharge
11 else if amount >= 25
11 10
T
12 shipcharge = 7 + rushcharge
13 else 13 12
13 shipcharge = 5 + rushcharge
14 endif 14
14 total = amount + tax + shipcharge
# of independent path = 7
45
Conclusion Example about Control Flow-Based Coverage
Flowgraph:
6 7
F 10
T
2,3,4 5 9 T 9` 14
F
12
Test Cases:
46
Oct 20,
2.2 Structural Testing: Data Flow-Based Testing 05
2.2.1 Define/Use Testing
Introduction:
- Many failures involve because of execution of an incorrect variable definition:
o Incorrect assignment
o Predicate is faulty
o Definition is missing
- Explore sequence event related to the data (variable) state
- Examples:
Dataflow Anomalies:
- Suspicious and data in a program
o Not errors to be detected by the compiler
o Represent potential problem or bad programming style
- Example of anomalies:
o live variable problem; a variable is defined twice before its used:
X = a;
:
: no use of X
X = b;
o A variable is defined but never used
o A variable is used but never defined
o Unreferenced labels
o Unreachable code
47
Normal Dataflow Condition:
- du
- kd Dataflow Anomalies
- uu
- _d (last definition) dd define followed by define *
- k_ (ok, last thing done) dk defined then killed
- u_ (ok, last use) ku killed then used
__ nothing happens
_k nothing to kill
Example on Normal Dataflow Condition: _u undefined
d_ defined but not used
u_ normal unless the variable
should have been killed
Path 1 Path 2
Define X
Use Y
Kill Z
Define X Kill Z
Use X Use X
Use Z Define Z
Define Y
Use Z
Use Y
Use Z
48
Kill Y
Define Z
Dataflow
RespectDefinition:
to X
- Path 1 (the concern about define X in
- 2G(P)
nd program graph
node)
o
o _d P program
(normal)
k, oo
u, ddd
V P's Variables
(concern)
u
- PATH o (P)du (normal) d, k
- Patho2 Paths in P u d
- DEFo (v,n) <variable, node>
du (normal) d
Respectoto v
Y V
- Path1
o n G(P) u, k
o _u (bad)
o ud (ok) at n
o v defined
- USEo (v,n) Types of USE(v,n)
du(normal)
oo ukv (normal)
V P-use: # of out-degree 2
- Path 2 C-use: # of out-degree 1
oo _un (bad)
G(P)
oo udv is(ok)
used at n
o dk(definition-use)
- du-path (probable error)
Respectoto A
Z path in PATH(P) such that for some v V, there is DEF(v,m) & USE(v,n) such
- Path1 that m & n are initial and final nodes of the path.
o _k(definition-clean
- dc-path (problem) path)
o ku (problem)
oo uuFor(normal)
a v V, dc-path is a path PATH (P) with initial & final nodes DEF(v,m),
o ud USE(v,n), such that no other node in the path is a defining node of V.
(normal)
- Path 2
o _k (problem)
Example 1:
o kk (probable problem)
o kd (normal)
1 i :=0;
o du (normal)
2 while (i<2) DU-Paths USE DEF Variable
o uu (normal) <1-2> 2 1
3 {
4 cout << "in loop"; <1-2-3-4-5> 5 1
i
5 i++; <5-6-2> 2 5
6 } Disallowed 5 5
Example 2:
Test
1 sum :=0; DU-Paths USE DEF Variable
Cases *
2 read(n); n=0 <2-3-4> 4 2 n
3 i=1; n=5 6 5 num
4 while (i <= n) {
5 read (num);
n=5 6 1
6 sum += num n=0 9 1
n=5 sum
7 i++; Disallowed 6 6
8 } n=5 9 6
9 print(sum) n=0 4 3
n=5 7 3
n=5 i
4 7
n=5 Disallowed 7 7
* Note: Two sets of data cover all the DU-Paths:
n=0 and n=5
49
Example on Define/Use Testing ('Commission' Program)
13 Input(locks)
14 While NOT(1ocks = -1) 'loop condition uses -1 to indicate end of data
15 Input(stocks, barrels)
30-33 34 7-13
35-37 38 14
39 15-19
20-28
40
29
41-42
16 totalLocks = totalLocks + locks
17 totalStocks = totalStocks + stocks
18 totalBarrels = totalBarrels + barrels
19 Input(stocks)
20 EndWhile
50
36 commission = 0.10 * 1000.0
37 commission = commission + 0.15*(sales-1000.0)
38 Else commission = 0.10 * sales
39 EndIf
40 EndIf
51
Oct 27,
Example on Define/Use Testing ('Commission' Program) (Cont.) 05
DEF/USE Paths:
Du-Paths DEF USE DEF Variable #
Clear Node Node
P1=<7,8,9,10,11,,21,22,23,24> Yes 24 7 lockPrice 1
P2=<8,9,10,11,12,,22,23,24,25> Yes 25 8 stockPrice 2
P3=<9,10,11,12,13,,23,24,25,26> Yes 26 9 barrelPrice 3
P4=<10,11,12,13,14,15,16> Yes 16 10 totalLocks 4
P5=<P4,17,18,19,20,21> No 21 10 totalLocks 5
P6=<P5,22,23,24> No 24 10 totalLocks 6
Note: Ignoring the possible repetition of the
while-loop
P7=<16,16> or Yes 16 16 totalLocks 7
<16,17,18,19,20,14,15,16>
Disallowed as du-paths
P8=<16,17,18,19,20,21> Yes 21 16 totalLocks 8
P9=<P8,22,23,24> 24 16 totalLocks 9
P10=<11,12,13,14,15,16,17> Yes 17 11 totalStocks 10
P11=<P10,18,19,20,21,22> No 22 11 totalStocks 11
P12=<P11,23,24,25> No 25 11 totalStocks 12
Disallowed as du-paths Yes 17 17 totalStocks 13
P14=<17,18,19,20,21,22> No 22 17 totalStocks 14
P15=<P14,23,24,25> No 25 17 totalStocks 15
P16=<12,13,14,15,16,17,18> Yes 18 12 totalBarrels 16
P17=<P16,19,20,21,22,23> No 23 12 totalBarrels 17
P18=<P17,24,25,26> No 26 12 totalBarrels 18
Disallowed as du-paths Yes 18 18 totalBarrels 19
P20=<18,19,20,21,22,23> Yes 23 18 totalBarrels 20
52
Example on Define/Use Testing ('Commission' Program) (Cont.)
53
DU-Path Test Coverage Metrics (Rapps-Weyuker dataflow metrics)
- All-Defs Criterion:
Annotations:
For every variable v V, T contains def-clear paths from every defining
node of V to a use of V
P Program
G(P) Graph of P
- All-Uses Criterion:
V Variables in P
For every variable v V, T contains def-clear paths from every defining T Paths in P
node of v to every use of v, and to successor node of each USE(v,n)
- All-P-Uses/Some-C-Uses:
For every variable v V, T contains def-clear paths from every defining node of v to
every predicate use of v; and if a definition of v has no P-uses, a def-clear leads to at
least one C-use
- All-C-Uses/Some-P-Uses:
For every variable v V, T contains def-clear paths from every defining node of v to
every C-use of v; and if a definition of v has no C-uses, a def-clear path leads to at
least one P-use
- All-DU-Paths:
For every variable v V, T contains def-clear paths from every defining node of v to
every use of v and to successor node of each USE(v,n) and that these paths are
either single loop traversals or they are cycle.
All-Paths
All-DU-Paths
All-Uses
All-C-Uses/Some-P-Uses All-P-Uses/Some-C-Uses
All-Defs All-P-Uses
All-Edges
All-Nodes
Subsumption Graph
54
Frankl and Weyuker's seven data flow criteria
- All-defs:
requires that for each definition of a variable X in P, the set of paths P executed by
the test set T contains a definition-clear subpath from the definition to at least one c-
use or one p-use of X.
- All-c-uses:
requires that for each definition of X in P, and each c-use of X reachable from the
definition, Pi contains a definition-clear subpath from the definition to the c-use.
- All-p-uses:
requires that for each definition of X in P, and each p-use of X reachable from the
definition, Pi contains a definition-clear subpath from the definition to the p-uses.
- All-c-uses/some-p-uses:
requires that for each definition of X in P, if there exists at least one c-use of X
reachable from the definition, Pi contains a definition-clear subpath from the
definition to at all reachable c-uses of X, otherwise, Pi contains a definition-clear
subpath from the definition to a reachable p-use of X.
- All-p-uses/some-c-uses:
requires that for each definition of X in P, if there exists at least one p-use of X
reachable from the definition, Pi contains a definition-clear subpath from the
definition to all reachable p-uses of X, otherwise, Pi contains a definition-clear
subpath from the definition to a reachable c-use of X.
- All-uses:
requires that for each definition of X in P, Pi contains a definition-clear subpath from
the definition to all reachable c-uses and p-uses of X.
- All-du-paths:
requires that for each definition of X in P, Pi contains all definition-clear subpaths
from the definition to all reachable c-uses and p-uses of X, such that each subpath
contains no loops, or contains one complete loop.
In addition: All-paths require that all paths through the program be executed.
55
Nov 3, 05
2.2 Structural Testing: Data Flow-Based Testing
2.2.2 Slice-Based Testing
Introduction:
- A program slice is a subset of a pgm
- Enables programmers to view subsets of a pgm by filtering out code that is not
relevant.
- Why is it useful?
o More manageable.
o When testing, debugging, or understanding, most code is irrelevant.
o Pgm slicing provides a convenient way to filtering out irrelevant code
o Slices can be computed by static analysis.
- Definitions:
o P is a pgm
o V is a subset of variables at line #n
o A slice S(v,n) produces a portion of a pgm that contributes to the value of v
just before statement at n.
o S(v,n) must be derived from P (by deleting statements)
o S(v,n) must be syntactically correct.
o For all execution of P, the value of v in the execution of S(v,n) just before
location n must be the same value of in execution of P just before n.
56
Example on Slice-Based Testing
57
Mutation Testing
Mutation Testing:
- A testing techniques that focuses on measuring the adequacy of test cases
- Not a testing strategy
- Should be Slice S (av, 24): used in conjunction with
0 main() {
traditional techniques
1 int mx, mn, av;
- Goal: 2 int tmp, num; cause the mutant programs to
fail (thus 4 tmp = readInt( ): showing the effectiveness of
test 7 sum = tmp; cases)
- Faults are 8 num = 1; introduced into the pgm by:
1. 10 while(tmp >= 0) Creating many versions of
11 { pgm called mutants
16 sum += tmp;
2. Each mutant contains a single
17 ++num;
18 tmp = readInt( ); fault.
3. 19 } Test cases are applied to the
21 av = sum / num; original pgm & mutants
4. If 24 printf("\nAvg=%d", av); the original pgm of all
mutants generate the same
output, the test case is inadequate.
- A test case is shown to be adequate by finding at least one mutant that generates a
different output.
- Theoretical analysis as well experiments result show that it is an effective approach
to measure the adequacy of test cases
Mutation Score:
- A mutation score of a set of test cases is the percentage of non-equivalent mutants
killed.
D
Mutation Score * 100
NE
- (we need it to be 100%)
where D is dead mutants
N is # of mutants
E is # of equivalent mutants
58
2.3 Structural Testing: Retrospective on Structure Testing
Observation:
- DF: for pgms that are computationally intensive
- Path/cyclomatic metric are more criteria metrics, not procedures:
o e.g., Basis Path gives a lower boundary on how much testing is necessary.
o Slice composition should be used to redevelop difficult sections of code
o Statement & Branch Coverage must be an absolute minimum (mandatory?)
testing reg.
59
Types of Testing DON'T Like to See
During a particularly long and painful bout of REGRESSION TESTING our application
software, my buddies and I came up with this list of other types of testing we'd like not to
see:
CONGRSSIONAL TESTING: Are you now, or have you ever been a bug?
DIGRESSION TESTING: Well, it works, but can I tell you about my truck...
OBSESSION TESTING: I'll find this bug if it's the last thing I do.
60
3. Integration Testing
Introduction:
- Testing activities that integrate software components together.
- Definition: is a systematic technique for constructing the software architecture while
at the same time conducting tests to uncover errors associated with interfacing.
- Objective: to take unit tested components and build a program structure that has
been dictated by design.
- Several approaches:
1. Decomposition-Based Integration: using the functional decomposition tree.
a. Top-down Integration
b. Bottom-up Integration
c. Sandwich Integration: a combination of top-down and bottom-up
integration.
2. Call Graph-Based Integration: using a direct graph
a. Pair-Wise Integration
b. Neighborhood Integration
3. Path-Based Integration (MM-Path Based Integration)
61
Figure: Driver vs. Stub (pressman, 2005)3.1 Integration Testing: Decomposition-
Based Integration
1. Top-down Integration:
- What are the steps for top-down integration?
1. The main control module is used as a test driver and stubs are
substituted for all components directly sub-ordinate to the
main control module.
2. Depending on the integration approach selected ( i.e., depth or
breadth first), sub-ordinate stubs are replaced one at a time
with actual components.
3. Tests are conducted as each component is integrated.
4. On completion of each set of tests, another stub is replaced
with the real components.
5. Regression testing may be conducted to ensure that new errors
have not been introduced.
The process continues from step 2 until the entire program
structure is built.
2. Bottom-up Integration:
- What are the steps for bottom-up integration?
1. Low-level components are combined into clusters (sometimes
called builds) that perform a specific software sub-function.
2. A driver (a control program for testing) is written to
coordinate test case input and output.
3. The cluster is tested.
4. Drivers are removed and clusters are combined moving
upward in the program structure.
62
3.2 Integration Testing: Call Graph-Based Integration
Introduction
- Move away from a purely structural basis toward a behavioral basis.
- Eliminate the stub/driver development effort.
1. Pair-Wise Integration:
- Use actual code instead of stubs/drivers.
- Cover each edge.
- Restrict a test session to two pair of units (not big bang).
2. Neighborhood Integration:
- A neighbor is any node connected.
o A set of nodes that are one edge away from the given
node
o All intermediate predecessors (drives) and all immediate
successors (stubs).
- Pro: reduce the # of tests
- Con: problem isolating especially in large neighborhoods.
Neighborhoods = nodes - sink nodes
63
Nov 10,
3.3 Integration Testing: Path-Based Integration 05
Introduction:
- Combined unit testing and integration testing.
- When a unit executes, some path of source statements is traversed.
- Suppose that a call goes to another unit along such a path:
o Unit testing: suppress the call statement because Path-Based Integration Pros:
control eventually returns to the calling unit anyway.
o Integration testing: abandon the single-entry, single- 1. Hybrid of functional and
exit percept and treat such calls as an exit followed by structural testing.
an entry. 2. Coupled with actual system
- We need to refine some of the program graph concepts. behavior.
3. Cost by elimination of stub
New Definition: and driver development.
- Source node:
o A statement fragment at which some program execution begins or resumes.
o Each module will have at least one.
o The first executable statement in a unit is a source node
- Sink node:
o A statement fragment at which program execution ends.
o E.g. final statement in a program.
- Module Execution Path (MEP): Hints in MM-Path:
o A sequence of statements that begins with a source node and
ends with a sink node with no intervening sink node. Nodes are Modules
o Program graph may have multiple source and sink nodes Edges are messages
- Message:
o A programming language mechanism by which one unit transfers control to
another unit.
- MM-Path:
o Module to module path (recall DD-Path: decision to decision path)
o Interleaved sequence of Module Execution Paths (MEP) and messages An MM-Path
o An example of Module Execution Paths (MEP) and MM-Path:
MEP(A,1) = <1, 2, 3, 6>
MEP(A,2) = <1, 2, 4>
MEP(A,3) = <5, 6>
MEP(B,1) = <1, 2>
MEP(B,2) = <3, 4>
MEP(C,1) = <1, 2, 4, 5>
MEP(C,2) = <1, 3, 4, 5>
- MM-Path Graph:
o Given a sequence of units, MM-Path graph is a directed
graph in which nodes are modules, execution paths and
edges correspond to messages and returns from one unit
to another.
o Assumption, in integration testing, unit testing has
already been done.
o The front figure shows an example of MM-Path Graph.
64
Example on Integration Testing
1 Main integrationNextDate
Type Date
Month As Integer
Day As Integer
Year As Integer
EndType
Dim today As Date
Dim tomorrow As Date
2 GetDate(today) 'msg1
3 PrintDate(today) 'msg2
4 tomorrow = IncrementDate(today) 'msg3
5 PrintDate(tomorrow) 'msg4
6 End Main
65
Example on Integration Testing (Cont.)
66
Example on Integration Testing (Cont.)
Main (1, 2)
msg1
GetDate (34, 56, 57,58, 59,60,61, 62, 63, 64, 65, 66)
msg7
ValidDate (35, 36,37, 39,40, 41, 42))
msg6
lastDayOfMonth (21,22,23,24,32, 33)'point of message quiessence
ValidDate (43.45,46,47,48, 50, 51, 52, 54, 55)
GetDate (67)
'Main (3)
67
Static Program Testing Analysis:
1. Hoare Logic
Introduction:
- Hoare logic (also known as FloydHoare logic) is a formal system developed by the
British computer scientist C. A. R. Hoare, and subsequently refined by Hoare and
other researchers. It was published in Hoare's 1969 paper "An axiomatic basis for
computer programming". The purpose of the system is to provide a set of logical
rules in order to reason about the correctness of computer programs with the rigour
of mathematical logic.
- A programming language specification consists of a syntactic description and a
semantic description.
o Syntactic description: symbols we can use in a language
o Semantic Description: what phrases in a programming language mean.
- In specific phrase, using natural language to describe three things:
1. Pre-conditions
2. Invariant
3. Post-conditions
Prototype:
{P} C {Q}
where P and Q are assertions and C is a command. P is called {P} C {Q} reads:
the precondition and Q the postcondition. Assertions are
formulas in predicate logic. Whenever P holds of the state
before the execution of C, then
Two Types: Q will hold afterwards.
- Partial Correctness: if C does not terminate, then there is no
"after", so Q can be any statement at all. Indeed, one can choose Q to be false to
express that C does not terminate.
- Total Correctness: if C terminates and at termination Q is true, the expression
exhibits. Termination would have to be proved separately.
Loop Invariant:
- A constant (unchanging) predicate (constraint, fact)
- Unaffected by group of mathematical operations (program statements) under
consideration
o often the important identification of the program (states? the acceptance?
look a little deeply)
- Establishing a loop invariant:
o Define a predicate I that shows the logical relationship between i, s, and b
68
Example on Hoare Logic
Objective:
A program that stores in the sum of array b[0,,10] in S
The predicate I:
I: 1 i 11 ^ s = sum(b[k]) k=0, ..., i-1
Precondition: True
i:=1;
(1) I is true s:= b[0];
while (i<11)
s:=s+b[i];
(2) is true i:=i+1;
Do these affect I?
I : 1 i 11 ^ s = sum(b[k]) k=0, ..., i-1
1 1 < 11 ^ s+b[i]= sum(b[k]) k=0,i-1
0 1 < 11 ^ s+b[i]= sum(b[k]) k=0,i
0 1 < 11 ^ s+b[i]= sum(b[k]) k=0,i-1+b[i]
0 1 < 11 ^ s+b[i]= sum(b[k]) k=0,i-1+b[i]
0 1 < 11 ^ s = sum(b[k]) k=0,i-1
69
True ^ True
70
Static Program Testing Analysis:
2. Design by Contract (DBC)
Introduction:
- Software entities have obligations to other entities based upon formalized rules
between them.
- A functional specification, or 'contract', is created for each module in the system
before it is coded. Program execution is then viewed as the interaction between the
various modules as bound by these contracts.
- routines have explicit preconditions that the caller must satisfy before calling the
routine, and explicit postconditions that describe the conditions that the routine will
guarantee to be true after the routine finishes
- a contract takes the following general form: "If you, the caller, set up certain
preconditions, then I will establish certain other results when I return to you. If you
violate the preconditions, then I promise nothing."
- DBC is novel in recognizing that these contracts are so crucial to software correctness
that they should be part of the design process. In effect, DBC advocates writing the
assertions first.
- The notion of a contract extends down to the method/procedure level; the contract
for each method will normally contain the following pieces of information:
o Acceptable and unacceptable inputs
o Return values, and their meanings
o Error and exception conditions that can occur
o Side-effects
o Preconditions
o Postconditions
o invariants
o (Rarer) Performance guarantees, e.g., for time or space used
DBC Syntax:
- When you write a module, as part of this program, you have to follow the syntax:
Requirement
---
---
---
Programs
---
---
Ensure
---
---
71
Glossary
Taken from ADRION, W. R., BRANSTAD, M. A. & CHERNIAVSKY, J. C. (1982) Validation, Verification, and Testing of
Computer Software. ACM Comput. Surv., 14, 159-192.
Audit.
See DOD Development Reviews.
Branch Testing.
A test method satisfying coverage criteria that require that for each decision point each
possible branch be executed at least once. (See Section 2.5.)
Cause-Effect Graphing.
Test data selection technique. The input and output domains are partitioned into classes and
analysis is performed to determine which input classes cause which effect. A minimal set of
inputs is chosen that will cover the entire effect set. (See Section 2.4.)
Certification.
Acceptance of software by an authorized agent usually after the software has been validated
by the agent, or after its validity has been demonstrated to the agent.
Cyclomatic Complexity.
The cyclomatic complexity of a program is equivalent to the number of decision statements
plus
1. (See Section 2.5.)
DD (decision-to-decision) Path.
A path of logical code sequence that begins at an entry or decision statement and ends at a
decision statement or exit. (See Section 2.5.)
Debugging. The process of correcting syntactic and logical errors detected during coding.
With the primary goal of obtaining an executing piece of code, debugging shares with
testing certain techniques and strategies, but differs in its usual ad hoc application and local
scope.
72
DOD Development Reviews.
A series of reviews required by DOD directives. These include
(1) The Systems Requirements Review is an examination of the initial progress during the
problem definition stage and of the convergence on a complete system configuration.
Test planning and test documentation are begun at this review.
(2) The System Design Review occurs when the system definition has reached a point where
major system modules can be identified and completely specified along with the
corresponding test requirements. The requirements for each major subsystem are
examined along with the preliminary test plans. Tools required for verification support are
identified and specified at this stage.
(3) The Preliminary Design Review is a formal technical review of the basic design approach
for each major subsystem or module. The revised requirements and preliminary design
specifications for each major subsystem and all test plans, procedures, and
documentation are reviewed at this stage. Development and verification tools are further
identified at this stage. Changes in requirements will lead to an examination of the test
requirements to maintain consistency.
(4) The Critical Design Review occurs just prior to the beginning of the construction stage.
The complete and detailed design specifications for each module and all draft test plans
and documentation are examined. Again, consistency with previous stages is reviewed,
with particular attention given to determining if test plans and documentation reflect
changes in the design specifications at all levels.
(5) Two audits, the Functional Configuration Audit and the Physical Configuration Audit are
performed. The former determines if the subsystem performance meets the
requirements. The latter audit is an examination of the actual code. In both audits,
detailed attention is given to the documentation, manuals and other supporting material.
(6) A Formal Qualification Review is performed to determine through testing that the final
coded subsystem conforms with the final system specifications and requirements. It is
essentially the subsystem acceptance test.
Driver.
Code that sets up an environment and calls a module for test. (See Section 1.3.)
Dynamic Analysis.
Analysis that is performed by executing the program code. (See Section 2.7.)
Dynamic Assertion.
A dynamic analysis technique that inserts assertions about the relationship between
program variables into the program code. The truth of the assertions is determined as the
program executes. (See Section 2.7.)
Error Guessing. Test data selection technique. The selection criterion is to pick values that
seem likely to cause errors. (See Section 2.4.}
Exhaustive Testing. Executing the program with all possible combinations of values for
program variables. (See Section 2.1.)
Extrenal Test Data. Test data that is at the extreme or boundary of the domain of an input
variable or which produces results at the boundary of an output domain. (See Section 2.4.)
Functional Testing.
Application of test data derived from the specified functional requirements without regard to
the final program structure. (See Section 2.4.)
Infeasible Path.
73
A sequence of program statements that can never be executed. (See Section 2.5.)
Inspection.
A manual analysis technique in which the program {requirements, design, or code) is
examined in a very formal and disciplined manner to discover errors. (See Section 2.2.)
Instrumentation.
The insertion of additional code into the program in order to collect information about
program behavior during program execution. (See Section 2.7.)
Life-Cycle Testing.
The process of verifying the consistency, completeness, and correctness of the software
entity at each stage in the development. (See Section 1.)
Mutation Analysis.
A method to determine test set thoroughness by measuring the extent to which a test set
can discriminate the program from slight variants (mutants) of the program. (See Section
2.6.)
Oracle. A mechanism to produce the "correct" responses to compare with the actual
responses of the software under test. (See Section 2.1.)
Path Expressions.
A sequence of edges from the program graph which represents a path through a program.
(See Section 2.5.)
Path Testing.
A test method satisfying coverage criteria that each logical path through the program be
tested. Often paths through the program are grouped into a Testing of Computer Software
187 finite set of classes; one path from each class is then tested. (See Section 2.5.)
Program Graph.
Graphical representation of a program. (See Section 2.5.)
Proof of Correctness.
The use of techniques of mathematical logic to infer that a relation between program
variables assumed true at program entry implies that another relation between program
variables holds at program exit. (See Section 2.2.)
Regression Testing.
Testing of a previously verified program required following program modification for
extension or correction. (See Section 1.4.)
Simulation.
Use of an executable model to represent the behavior of an object. During testing the
computational hardware, the external environment, and even code segments may be
simulated. (See Section 2.2.)
Self-Validating Code.
74
Code which makes an explicit attempt to determine its own correctness and to proceed
accordingly. (See Section 2.7.)
Statement Testing.
A test method satisfying the coverage criterion that each statement in a program be
executed at least once during program testing. (See Section 2.5.)
Static Analysis,
Analysis of an program that is performed without executing the program. (See Section 2.7.)
Stress Testing.
See Boundary Value Analysis.
Structural Testing.
A testing method where the test data are derived solely from the program structure. (See
Section 2.5.)
Stub.
Special code segments that, when invoked by a code segment under test, will simulate the
behavior of designed and specified modules not yet constructed. (See Section 1.3.)
Symbolic Execution.
A static analysis technique that derives a symbolic expression for each program path. (See
Section 2.7.)
Test Driver.
A program that directs the execution of another program against a collection of test data
sets. Usually the test driver also records and organizes the output generated as the tests are
run. (See Section 1.3.)
Test Harness.
See Test Driver.
Testing.
Examination of the behavior of a program by executing the program on sample data sets.
Validation.
Determination of the correctness of the final program or software produced from a
development project with respect to the user needs and requirements. Validation is usually
accomplished by verifying each stage of the software development life cycle.
Verification.
In general, the demonstration of consistency, completeness, and correctness
of the software at each stage and between each stage of the development life cycle.
Walk-Through.
75
A manual analysis technique in which the module author describes the module's structure
and logic to an audience of colleagues. (See Section 2.2.)
76