400 likes | 585 Views
Introduction to Software Testing (2) This set of slides is best read with a colour display. Prof. T.H. Tse Department of Computer Science Email: thtse@cs.hku.hk Web: http://hku.hk/thtse. Data Flow Testing. Too simple.
E N D
Introduction to Software Testing (2)This set of slides is best read with a colour display Prof. T.H. Tse Department of Computer Science Email:thtse@cs.hku.hk Web:http://hku.hk/thtse
Data Flow Testing Too simple May need infinite number of test casesif the loop does not have fixed upper or lower bound • A white-box testing technique • Recall control flow testing • Statement coverage • Branch coverage • Path coverage • Loop coverage May not be possibleif the loop does not have fixed upper or lower bound. • In data flow testing, we are interested in tracing the flow of data amongprogram blocks.
Three Types of Variable Occurrences • Definition: The value of the variable is stored in a memory location • Example 1: x = 0; • Example 2: cin >> x; • Undefinition: The value or the location of the variable becomes unbound • Example: x = 1 / 0; • Use:The value of the variable is fetched from a memory location • Example: y = x+ 1;.
Two Types of Uses • Computation use(c-use):The value of the variable directly affects a computation or is part of an output • Example 1: y = x+ 1; • Example 2: y = (x== 0); • Example 3: cout << x; • Predicate use(p-use):The value of the variable directly affects a control flow (and may indirectly affect a computation) • Example: if (x == 0) { y = 1;} .
Block • A blockis a maximal sequence of simple statements such that • it can only be entered through the first statement • whenever the first statement is executed, the remaining statements are executed in sequential order.
Block: sqrtX = (lowGuess + highGuess) / 2; sqrtSquared = sqrtX * sqrtX; • Not block: while (fabs(sqrtSquared - x) >= 0.000001) { if (sqrtSquared < x) lowGuess = sqrtX; if (sqrtSquared > x) highGuess = sqrtX; sqrtX = (lowGuess + highGuess) / 2; sqrtSquared = sqrtX * sqrtX; } Examples
Flow Graph A subprogram under test is represented by a flow graph Nodes correspond to the blocks of the subprogram Edges indicate possible flows of control among blocks.
Example of FlowGraph ((x<=0)||(x>=1)) ((x>0)&&(x<1)) lowGuess = x; highGuess = 1; (fabs(sqrtSquared - x) < 0.000001) (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared < x) (sqrtSquared >= x) lowGuess = sqrtX; cout << sqrtX; (sqrtSquared <= x) (sqrtSquared > x) highGuess = sqrtX; cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX;
j i No definition or un-definition No definition or un-definition Definition Clear Path • A definition clear path with respect to x(def-clear path wrt x) is apath (i, n1, n2, ..., nm, j), where m≥ 0, containing no definitions or undefinitions of xin nodes n1, n2, ..., nm
Example of Definition Clear Path ((x>0)&&(x<1)) lowGuess = x; highGuess = 1; (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared >= x) (sqrtSquared > x) highGuess = sqrtX; sqrtX = (lowGuess + highGuess) / 2; sqrtSquared = sqrtX * sqrtX; cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess) / 2; sqrtSquared = sqrtX * sqrtX; No definition or un-definition No definition or un-definition
Global c-use • We define a c-use of a variable x in node i to be a global c-useif the value of x has been defined in some block other than block i.
Example of Global c-use cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess) / 2; sqrtSquared = sqrtX * sqrtX; ((x>0)&&(x<1)) lowGuess = x; highGuess = 1; (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared >= x) (sqrtSquared > x) highGuess = sqrtX; Not global c-use Global c-use
Global Definition • A node ihas a global definitionof a variable x if it has a definition of x and there is a def-clear path wrt x from node ito some node containing a global c-use or edge containing a p-use of x.
Example of Global Definition Global definitions sqrtX = (lowGuess + highGuess) / 2; sqrtSquared = sqrtX * sqrtX; (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared >= x) (sqrtSquared > x) highGuess = sqrtX; 14
Simple Path • A simple pathis one in which all nodes, except possibly the first and last, are distinct • Examples:
Not loop free: Loop-Free Path • A loop-free pathis one in which all nodes are distinct • Example:
nl nk nl=nk • ornj nkhas a p-use of x and (nl, n2, ..., nj)is a def-clear loop-free path with respect to x. nl nj nk du-Path • A path (nl, n2, ..., nj, nk)is a du-pathwith respect to a variable x if nl has a global definition of x and • eithernkhas a global c-use of x and (nl, n2, ..., nj, nk)is a def-clear simple path with respect to x
Example 1 of du-path Global definitions cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess) / 2; sqrtSquared = sqrtX * sqrtX; ((x>0)&&(x<1)) lowGuess = x; highGuess = 1; (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared >= x) (sqrtSquared > x) highGuess = sqrtX; p-use Global c-use
Example 2 of du-path (x != 0) cout << x; cin >> x; (x != 0) Global definition cin >> x; Global c-use Global definition
Data Flow Testing Coverage Criteriaall-defs Criterion • For every global definition node i of each variable x, the test cases cover at least onedef-clear path that goes from node ito at least onenode or edge at which the value assigned to x in node iis used.
Data Flow Testing Coverage CriteriaExample of all-defs Criterion n1 i1 n’1 p1 i2 p’1
Fault ExampleOne ((x<=0)||(x>=1)) ((x>0)&&(x<1)) lowGuess = x; highGuess = 1; (fabs(sqrtSquared - x) < 0.000001) (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared < x) lowGuess = sqrtX; cout << sqrtX; (sqrtSquared <= x) (sqrtSquared > x) highGuess = sqrtX; cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; (sqrtSquared >= x) lowGuess= sqrtX; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX;
((x<=0)||(x>=1)) (fabs(sqrtSquared - x) < 0.000001) (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared < x) (sqrtSquared >= x) (sqrtSquared >= x) lowGuess = sqrtX; cout << sqrtX; (sqrtSquared > x) highGuess = sqrtX; cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; Fault Example 1all-defs Criterion sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX;
cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; ((x<=0)||(x>=1)) (fabs(sqrtSquared - x) < 0.000001) (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared < x) lowGuess = sqrtX; Never executed cout << sqrtX; (sqrtSquared <= x) lowGuess = sqrtX; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; Fault Example 1Test Case x = 1
Data Flow Testing Coverage Criteriaall-uses Criterion • For every global definition node i of each variable x, the test cases cover at least onedef-clearpath that goes from node ito everynode or edge at which the value assigned to x in node iis used.
Data Flow Testing Coverage CriteriaExample of all-uses Criterion n1 i1 n’1 p1 i2 p’1
((x<=0)||(x>=1)) (fabs(sqrtSquared - x) < 0.000001) (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared < x) (sqrtSquared >= x) lowGuess = sqrtX; cout << sqrtX; (sqrtSquared > x) highGuess = sqrtX; cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; Fault Example 1all-uses Criterion sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX;
((x<=0)||(x>=1)) (fabs(sqrtSquared - x) < 0.000001) cout << sqrtX; cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; Fault Example 1Test Case x = 0
cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; ((x<=0)||(x>=1)) (fabs(sqrtSquared - x) < 0.000001) (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared < x) lowGuess = sqrtX; cout << sqrtX; (sqrtSquared <= x) sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; Fault Example 1Test Case x = 1
((x<=0)||(x>=1)) (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared >= x) (sqrtSquared > x) lowGuess = sqrtX; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; Fault Example 1Test Case x = 5 Infinite loop
Data Flow Testing Coverage Criteriaall-du-paths Criterion • For every global definition node i of each variable x, the test cases cover everydu-path that goes from node ito everynode or edge at which the value assigned to x in node iis used.
Data Flow Testing Coverage CriteriaExample of all-du-paths Criterion n1 i1 n’1 p1 i2 p’1
Fault ExampleTwo ((x<=0)||(x>=1)) ((x>0)&&(x<1)) lowGuess = x; highGuess = 1; (fabs(sqrtSquared - x) < 0.000001) (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared < x) lowGuess = sqrtX; cout << sqrtX; (sqrtSquared <= x) cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; lowGuess = x; highGuess = 0; (sqrtSquared >= x) (sqrtSquared > x) highGuess = sqrtX; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX;
Fault Example 2Test Cases x = 0, 1, 5 cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; ((x<=0)||(x>=1)) lowGuess = x; highGuess = 0; (fabs(sqrtSquared - x) < 0.000001) (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared < x) (sqrtSquared >= x) lowGuess = sqrtX; Never executed cout << sqrtX; (sqrtSquared <= x) (sqrtSquared > x) highGuess = sqrtX; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX;
((x<=0)||(x>=1)) ((x>0)&&(x<1)) lowGuess = x; highGuess = 0; (fabs(sqrtSquared - x) < 0.000001) (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared < x) (sqrtSquared >= x) lowGuess = sqrtX; cout << sqrtX; (sqrtSquared > x) highGuess = sqrtX; cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; Fault Example 1all-du-paths Crit’n sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX;
Fault Example 2Test Case x = 0.5 cin >> x; lowGuess = 0; highGuess = x; sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; ((x>0)&&(x<1)) lowGuess = x; highGuess = 0; (fabs(sqrtSquared - x) >= 0.000001) (sqrtSquared < x) lowGuess = sqrtX; (sqrtSquared <= x) sqrtX = (lowGuess + highGuess)/2; sqrtSquared = sqrtX * sqrtX; Infinite loop
Data Flow Testing Coverage CriteriaSubsumption Relationships Obviously, all-du-paths • all-uses • all-defs subsumes
Subsumption Relationships all-paths • all-du-paths • all-uses • all-defs may be infinite finite all-uses • all-edges branch coverage.
Advantage of Data Flow Testing over Control Flow Testing • Any sub-program has only finitely many definition-use associations, so that none of the data flow criteria requires an infinite amount of test data.
Challenge of Data Flow Testing Need to analyse every global definition, every c-use, every p-use and/or every du-path of every variable Hints Do not need to draw entire flow graph Label statements or blocks by numbers.