Lecture(Whitebox testing) software engineering
Lecture(Whitebox testing) software engineering
LECTURE # 6
White box testing (a.k.a. clear box testing, glass box testing, transparent box
testing, translucent box testing or structural testing)
The tests written based on the white box testing strategy incorporate coverage
of the code written, branches, paths, statements and internal logic of the code
etc.
In order to implement white box testing, the tester has to deal with the code
and hence is needed to possess knowledge of coding and logic i.e. internal
working of the code. White box test also needs the tester to look into the code
and find out which unit/statement/chunk of the code is malfunctioning.
In the language of V&V, White box testing is often used for verification
(Are we building the software right?)
White Box Testing
Using White box testing methods, the software engineer can derive test cases
that:
ii) And it is nearly impossible to look into every bit of code to find
out hidden errors, which may create problems, resulting in failure of
the application.
Control Flow Testing
In flow graph each circle (a flow graph node) represents one or more
procedural statements.
A sequence of process boxes and a decision diamond can map into a single
node.
The arrows on the flow graph called edges or links represents flow of control.
An edge must terminate at a node even if the node does not represent any
procedural statements.
C
If C Then S1 else S2;
Sequential statement block
S1 S2
C Case C of
C
L1: S1; If C Then S1;
S1 Sn L2: S2;
…
Kn: Sn; S1
end;
Program Flow Graph (Control Flow Diagram)
C I=1
While C do S; For loop:
F for I = 1 to n do S;
T S
S
yes
I <=n
no
S1 Do loop:
do S1 until C;
F
C
T
Program Flow Graph (Control Flow Diagram)
White-Box Software Testing Methods
White Box Testing tends to involve the Coverage of the Specification in the
Code.
1. Statement Coverage
2. Segment Coverage
3. Branch Coverage
7. Loop Testing
Code Coverage
It is a form of testing that looks at the code directly and as such comes under
the heading of white box testing.
Code Coverage Types
Statement Coverage:
In this type of testing the code is executed in such a manner that
every statement of the application is executed at least once. It helps in
assuring that all the statements execute without any side effect.
Segment/Function coverage:
Each segment of code executed at least once. It ensures that all
functions are exercised at least once.
Branch Coverage:
A branch is the outcome of a decision, so branch coverage simply
measures which decision outcomes have been tested. Each branch in the
code is taken in each possible direction at least once.
Loop Testing:
This strategy relate to testing single loops, concatenated loops,
and nested loops. Loops are fairly simple to test unless dependencies exist
among the loop or b/w a loop and the code it contains.
What is coverage?
20
A Simple Example of Coverage
if ( a < b and c == 5) { Statement coverage:
Test case (a)
y++;
Branch coverage:
}
x = 5; Test cases (a) and (b)
(Basic) Condition coverage:
* and is interpreted as logical-and
Test case (b) and (c)
Problem: and (&&) short circuits!
And second half of (c) not executed.
Test cases:
Branch-Condition coverage:
(a) a < b, c == 5 Test case (a) (b) and (c)
(b) a < b, c != 5 Compound condition coverage:
(c) a >= b, c == 5 Test case (a) (b) (c) and (d)
(d) a >= b, c != 5
21
Statement Testing
• Adequacy criterion:
– each statement (or node in the CFG) must be executed at least once
• Coverage: # executed statements
# statements
• Rationale:
– A defect in a statement can only be revealed by executing the faulty
statement
22
Statement Coverage: Example
• Test requirements
– Nodes 3, …, 9
• Test cases
– (x = 20, y = 30)
23
Statement Coverage: Example
• Test requirements
– Nodes 3, …, 9
• Test cases
– (x = 20, y = 30)
Such test does not reveal the fault at
statement 7
To reveal it, we need to traverse edge 4-7
=> Branch Coverage
24
Branch Testing
• Adequacy criterion:
– each branch (edge in the CFG) of every selection
statement (if, switch) must be executed at least once
• Coverage: # executed branches
# branches
25
Statements vs. Branches
• Traversing all edges of a graph causes all nodes
to be visited
– Satisfying branch adequacy implying satisfying the
statement adequacy
• The converse is not true
– A statement-adequate (or node-adequate) test suite
may not be branch-adequate (edge-adequate)
26
Branch Coverage: Example
• Test requirements
– Edges 4-6, Edges 4-7
• Test cases
– (x = 20, y = 30)
– (x = 0, y = 30)
27
Branch Coverage: Example
1. main() {
2. int x, y, z, w;
• Branch Coverage
3. read(x);
4. read(y); • Test Cases
5. if (x ! = 0) – (x = 1, y = 22)
6. z = x + – (x = 0, y = -10)
10;
7. • Is the test suite adequate for
else
8. branch coverage?
z = 0;
9.
if (y>0)
10.
w = y / z;
11. }
12.
28
Branch Coverage: Example
1. main() {
• Branch Coverage
2. int x, y, z, w;
3. read(x); • Test Cases
4. read(y); – (x = 1, y = 22)
5. if (x ! = 0) – (x = 0, y = -10)
6. z = x + 10; • Is the test suite adequate for
7. else branch coverage?
8. z = 0;
• Yes, but it does not reveal the
9. if (y>0)
fault at statement 10
10. w = y / z;
• Test case (x = 0, y = 22)
11.
12. } • Reveals fault
29
Branch Coverage: Example
30
Cyclomatic Complexity
Cyclomatic complexity is a software metric that provides a quantitative
measure of the global complexity of a program.
When this metric is used in the context of the basis path testing, the value
computed for cyclomatic complexity defines the number of independent paths
in the basis set of a program.
where E is the number of flow graph edges and N is the number of flow graph
nodes.
1 node
No. of regions = 4
(considering the universal region)
edge 2 3
No. of edges = 9
4 No. of nodes = 7
6 V(G) = 9 - 7 + 2 = 4
7
Graph Matrices
Graph Matrix is a data structure that assists in basis path testing.
A graph matrix is a square matrix whose size is equal to the number of nodes
on the flow graph. Each row and column corresponds to an identified
node, and matrix entries corresponds to connections between nodes.
Referring to the figure each node on the flow graph is identified by numbers,
while ach edge is identified by the letters. A letter entry is made in the
matrix to correspond to a connection between two nodes. For example
node 3 is connected to node 4 by edge b.
1
a
e b d
5 4
f
c
g
2 FLOW GRAPH
Graph Matrices
The link weight 1(a connection exists) and 0(a connection does not exists).
NODE 1 2 3 4 5
1 a
2
3 d b
4 c f
5 g e
Graph Matrix
Graph Matrices
Graph Matrix is redrawn here each letter has been replaced with a 1, indicating
that a connection exists (zeros has been excluded for clarity).
NODE 1 2 3 4 5
1 1
2
3 1 1
4 1 1
5 1 1
Connection Matrix
White-Box Software Testing Methods
Basic path testing (a white-box testing technique):
Step 4: Prepare test cases that will force execution of each path in the
basis set.
Step 5: Run the test cases and check their results
An Example
1 2 3 4 5 6 7
1 node
1 a
a b 2 b d
edge 2 3 3 c
d c 4 e i
5 f
4 6 g h
7
e
i 1 2 3 4 5 6 7
5 g
f region 1 1 1-1=0
2 1 1 2 - 1 =1
6 1 -1 = 0
3 1
4 1 1 2 - 1 =1
h
5 1 1 -1 = 0
7 6 1 1 2 -1 = 1
7
--------
3 +1 = 4
Condition Testing
Condition testing is a test case design method that exercises the logical
conditions contained in a program module. A simple condition is a
Boolean variable or a relational expression. A relational expression takes
the form
Where E1 and E2 are arithmetic expressions and < relational operator> is one
of the following: {<, , >, , =, }
A B C A&B or C
Certainly, this list is by far not complete, but it gives a good impression of
possible faults. It is known from experience that, if programs pass most
of this tests, the number of bugs found by other tests is, according to
expectations, lots lower.
Data Flow Testing
Data-flow testing is a white box testing technique that can be used to detect
improper use of data values due to coding errors. Errors are inadvertently
introduced in a program by programmers. For instance, a software
programmer might use a variable without defining it.
Additionally, he/she may define a variable, but not initialize it and then use
that variable in a predicate.
e.g. int x ;
if (x ==100) {};
There are four ways data can be used: defined, used in a predicate, used in a
calculation, and killed.
Data-flow testing monitors the lifecycle of a piece of data and looks out for
inappropriate usage of data during definition, use in predicates,
computations and termination (killing). It identifies potential bugs by
examining the patterns in which that piece of data is used.
Loop testing is a white box testing technique that focuses on the validity of
loop constructs. Four different classes of loops can be defined:
1. Simple loops
2. Concatenated loops
3. Nested loops
4. Unstructured loops
Simple Loops
The module interface is tested to ensure that information properly flows into
and out of the program unit under test.
The local data structure is examined to ensure that data stored temporarily
maintains its integrity during all steps in an algorithm’s execution.
Boundary conditions are tested to ensure that the module operates properly
at boundaries established to limit or restrict processing.
All independent paths through the control structure are exercised to ensure
that all statements in a module have been executed at least once.
Selective testing of execution paths is an essential task during the unit test.
Test Cases should be designed to uncover errors due to erroneous
computations, incorrect comparisons, or improper control flow.
Unit Test Procedures
After source level code has been developed, reviewed, and verified for
correspondence to component level design, unit test case design begins.
Because the components is not the stand alone program, driver or stub
software must be developed for each unit test.
Drivers and stubs both represent overhead, that is both are software that
must be written but that is not delivered with the final software product.
Unit Test Procedures
Any question