Download presentation
1
Chapter 2 : Graph Coverage (part 2)
Introduction to Software Testing
2
Structural Graph Coverage for Source Code
The most widely used graph coverage criteria are defined on source code, although details vary from one programming language to another. First step for applying a graph criteria is to define the graph for source code. The most common graph is control flow graph (CFG). CFG associate an edge with each possible branch in the program, and a node with sequences of statements. Basic Block A Maximum sequence of program statements such that if any one statement of the block is executed, all statements in the block are executed.
3
Structural Graph Coverage for Source Code
Example 1: CFG of if-else structure in two basic blocks: decision node: A node which represents the conditional test x < y has more than one out-edge (for example n0). junction node: A node which has more than one in-edge (for example n3).
4
Structural Graph Coverage for Source Code
Example 2: CFG for the if structure without else: Example 3: CFG for while loop structure:
5
Structural Graph Coverage for Source Code
Node n1 in example 3 is a dummy node because it doesn’t represent any statements, but gives the iteration edge (n2, n1) somewhere to go. A common mistake for beginners: try to have the edge go to n0. This isn’t correct because that would mean the initialization step is done each iteration of the loop. CFG for a for loop structure is different from that of the while loop: We show the increment of x in a different node than the method call y = f(x,y). This violates the definition of a basic block and the two nodes should be combined.
6
Structural Graph Coverage for Source Code
Example 4: CFG of for loop structure: Example 5: CFG of case structure:
7
Data Flow Graph Coverage for Source Code
def A def is a location in the program where a value for a variable is stored into memory (assignment, input, etc.). A def may occur for variable x in the following situations: x appears on the left side of an assignment statement. x is an actual parameter in a call site and its value is changed within the method. x is a formal parameter of a method (an implicit def when the method begins execution). x is an input to the program
8
Data Flow Graph Coverage for Source Code
Some features of programming languages greatly complicate this simple definition for def: Is a def of an array variable a def of the entire array, or of just the element being referenced? What about objects? Should the def consider the entire object, or only a particular instance variable of the object? If two variables reference the same location, that is, the variables are aliases, how is the analysis done? What is the relationship between coverage of the original source code, optimized source code, and the machine code? We omit these complicating issues in our course.
9
Data Flow Graph Coverage for Source Code
use A use is a location where a variable’s value is accessed. A use may occur for variable x in the following situations: x appears on the right side of an assignment statement. x appears in a conditional test (note that such a test is always associated with at least two edges). x is an actual parameter to a method. x is an output of the program. x is an output of a method in a return statement or returned as a parameter.
10
Data Flow Graph Coverage for Source Code
Consider the following statements that reference local variables (ignoring concurrency): y = z; x = y + 2; The use of y in the second statement is called a local use. It is impossible for a def in another basic block to reach the use in x = y + 2. The reason is that the definition of y in y = z, always overrides any definition of y from any other basic block: no def-clear path goes from any other def to that use.
11
Data Flow Graph Coverage for Source Code
The use of z is called global, because the definition of z used in this basic block must originate in some other basic block. Data flow analysis only considers global uses. Example : Dataflow analysis for a simple string pattern matching program called TestPat written in Java: public class TestPat { public static void main (String[] argv) final int MAX = 100; char subject[] = new char[MAX]; char pattern[] = new char[MAX];
12
Data Flow Graph Coverage for Source Code
if (argv.length != 2) { System.out.println("java TestPat String-Subject String-Pattern"); return; } subject = argv[0].toCharArray(); pattern = argv[1].toCharArray(); TestPat testPat = new TestPat (); int n = 0; if ((n = testPat.pat (subject, pattern)) == -1) System.out.println("Pattern string is not a substring of the subject string"); else System.out.println("Pattern string begins at the character " + n); public TestPat () { } public int pat (char[] subject, char[] pattern) // Post: if pattern is not a substring of subject, return -1, else return (zero-based) index where the pattern (first) starts in subject
13
Data Flow Graph Coverage for Source Code
final int NOTFOUND = -1; int iSub = 0, rtnIndex = NOTFOUND; boolean isPat = false; int subjectLen = subject.length; int patternLen = pattern.length; while (isPat == false && iSub + patternLen - 1 < subjectLen) { if (subject [iSub] == pattern [0]) { rtnIndex = iSub; // Starting at zero isPat = true; for (int iPat = 1; iPat < patternLen; iPat ++) { if (subject[iSub + iPat] != pattern[iPat]) rtnIndex = NOTFOUND; isPat = false; break; // out of for loop } iSub ++; return (rtnIndex);
14
Data Flow Graph Coverage for Source Code
CFG for TestPat:
15
Data Flow Graph Coverage for Source Code
List the defs and uses at each node in the CFG for TestPat:
16
Data Flow Graph Coverage for Source Code
List of defs and uses at each edge in the CFG for TestPat:
17
Data Flow Graph Coverage for Source Code
List of du-paths for each variable in TestPat followed by all the du-paths for each du-pair:
18
Data Flow Graph Coverage for Source Code
cont.
19
Data Flow Graph Coverage for Source Code
The fourth column, ”prefix?” Several def/use pairs have more than one du-path in TestPat. For example, the variable iSub is defined in node 2 and used in node 10. Three du-paths exist: [2,3,4,10](iSub) [2,3,4,5,6,10](iSub) [2,3,4,5,6,7,8,10](iSub) One optimization uses the fact that a du-path must be toured by any test that tours an extension of that du path. These du-paths are marked with the annotation Yes in the ”prefix?” column.
20
Data Flow Graph Coverage for Source Code
Test paths to satisfy all du-paths coverage on TestPat:
21
Graph coverage for Design Elements
Using data abstraction and object-oriented software has led to an increased emphasis on modularity and reuse. Testing of software based on various parts of the design (design elements) is becoming more important. Associated with Integration Testing One of the benefits of modularity is that the software components can be tested independently.
22
Structural Graph coverage for Design Elements
Graph coverage for design elements usually starts by creating graphs that are based on couplings between software components. Coupling measures the dependency relations between two units by reflecting their interconnections. Faults in one unit may affect the coupled unit. Most test criteria for design elements require that various connections among program components be visited. call graph: The nodes represent methods and the edges represent method calls. Most common graph used for structural design coverage.
23
Structural Graph coverage for Design Elements
Example: A simple call graph for a small program that contains six methods. Method A calls B, C, and D, and C in turn calls E and F, and D also calls F.
24
Structural Graph coverage for Design Elements
method coverage Node coverage requires that each method be called at least once. call coverage Edge coverage requires that each call be executed at least once. module coverage A module is collection of related units, for example a class is Java’s version of a module. Instead of being able to obtain one connected call graph, we may generate several disconnected call graphs. Module testing with this technique is not appropriate. Techniques based on sequences of calls are needed.
25
Structural Graph coverage for Design Elements
Inheritance hierarchy The most obvious graph to create for testing object-oriented language features is the inheritance hierarchy. In OO programming, classes are not directly tested because they are not executable. In fact, the edges in the inheritance hierarchy do not represent execution flow at all, but rather inheritance dependencies. To apply any type of coverage, we first need a model for what coverage means. The first step is to require that objects be instantiated for some or all of the classes.
26
Structural Graph coverage for Design Elements
A simple inheritance hierarchy: inheritance hierarchy with objects instantiated:
27
Structural Graph coverage for Design Elements
Inheritance hierarchy (cont.) The most obvious interpretation of node coverage for this graph is to require that at least one object be created for each class. The logical extension is to require that for each object of each class, the call graph must be covered according to the call coverage criterion. OO call coverage criterion can be called an aggregation criterion because it requires call coverage to be applied on at least one object for each class. all object call criterion requires that call coverage be satisfied for every object that is instantiated for every class.
28
Data Flow Graph Coverage for Design Elements
Control connections among design elements are simple and tests based on them are not very effective at finding faults. Data flow connections are often very complex and difficult to analyze. When testing program units, the defs and uses are in the same unit. During integration testing, defs and uses are in different units.
29
Data Flow Graph Coverage for Design Elements
A caller is a unit that invokes another unit, the callee. The statement that makes the call is the call site. An actual parameter is in the caller; its value is assigned to a formal parameter in the callee. The interface between two units is the mapping of actual to formal parameters. The underlying premise of the data flow testing criteria for design elements is that it must be ensured that variables defined in caller units be appropriately used in callee units. This technique can be limited to the unit interfaces.
30
Data Flow Graph Coverage for Design Elements
An example of parameter coupling that the data flow criteria will test:
31
Data Flow Graph Coverage for Design Elements
Types of data flow couplings: parameter coupling : parameters are passed in calls. shared data coupling : two units access the same data object as a global or other non-local variable. external device coupling : two units access the same external medium such as a file. In the following, all examples will be in terms of parameters but the concepts apply equally to shared data and external device couplings. coupling variable Variables that are defined in one unit and used in another.
32
Data Flow Graph Coverage for Design Elements
Last-def The set of nodes that define a variable x for which there is a def-clear path from the node through the call site to a use in the other unit. The variable can be passed as a parameter, a return value, or a shared variable reference. use-clear A path from ni to nj is use-clear with respect to variable v if for every node nk on the path, k <> i and k <> j , v is not in use(nk).
33
Data Flow Graph Coverage for Design Elements
First-use The set of nodes that have uses of y and for which there exists a path that is def-clear and use-clear from the entry point (if the use is in the callee) or the call site (if the use is in the caller) to the nodes. An Example of coupling du pairs: The callsite has two du-pairs; x in caller F() is passed to a in callee G() and b in G() is returned and assigned to y in F().
34
Data Flow Graph Coverage for Design Elements
last-defs and first-uses between two units with two partial CFGs:
35
Data Flow Graph Coverage for Design Elements
coupling du-path A coupling du-path is a path from a last-def to a first-use. All-Coupling-Def coverage All-Defs coverage requires that a path be executed from every last-def to at least one first-use. All-Coupling-Use coverage All-Uses coverage requires that a path be executed from every last-def to every first-use. All-Coupling-du-Paths coverage All-du-Paths coverage requires that we tour every simple path from every last-def to every first-use.
36
Data Flow Graph Coverage for Design Elements
The flow of data along couplings between callers and callees is only one type of a very complicated set of data definition and use pairs. Example. Def-use pairs under intra-procedural and inter-procedural data flow:
37
Data Flow Graph Coverage for Design Elements
full inter-procedural data flow Identifying all du-pairs between a caller (A()) and a callee (B()). coupling inter-procedural data flow Identifying du-pairs between last-defs and first-uses. Example. Def-use pairs in a OO software:
38
Data Flow Graph Coverage for Design Elements
Direct case for OO du-pairs: A coupling method F(), calls two methods A() and B(). A() defines a variable and B() uses it. Both A() and B() must be called through the same instance context, or object reference. Indirect case for OO du-pairs: A coupling method F() calls two methods M() and N(), which in turn call two other methods A() and B(). The def and use are in A() and B(), so the reference is indirect. There can be more than one call between the coupling method and the methods with the def and use. A() and B() could be in the same class, or they could be in different classes.
39
Data Flow Graph Coverage for Design Elements
Example. Def-use pairs in web applications and other distributed software: P1 and P2 are two processes, threads, or other distributed software components, and they call A() and B(), which def and use the same variable. message could be HTTP, RMI, or other mechanism. A() and B() could be in the same class or accessing a persistent variable such as in a web session. This very loosely coupled software can be expected to have far fewer du-pairs, but identifying them, finding def-clear paths between them, and designing test cases to cover them is quite complicated.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.