WHITE-BOX TESTING
(Source: Pressman, R. Software Engineering: A Practitioner’s Approach. McGraw-Hill, 2005)
WHITE BOX TESTING
Knowing the internal workings of a product, test that all
internal operations are performed according to
specifications and all internal components have been
exercised.
Involves tests that concentrate on close examination of
procedural detail
Logical paths through the software are tested
Test cases exercise specific sets of conditions and
loops
WHITE-BOX TESTING
Uses the control structure part of component-level design
to derive the test cases
These test cases
Guarantee that all independent paths within a module
have been exercised at least once
Exercise all logical decisions on their true and false
sides
Execute all loops at their boundaries and within their
operational bounds
Exercise internal data structures to ensure their validity
BASIS PATH TESTING
White-box testing technique proposed by Tom McCabe
Enables the test case designer to derive a logical
complexity measure of a procedural design
Uses this measure as a guide for defining a basis set of
execution paths
Test cases derived to exercise the basis set are
guaranteed to execute every statement in the program at
least one time during testing
FLOW GRAPH NOTATION
A circle in a graph represents a node, which stands for a sequence
of one or more procedural statements
A node containing a simple conditional expression is referred to as a
predicate node
A predicate node has two edges leading out from it (True and
False)
An edge, or a link, is a an arrow representing flow of control in a
specific direction
An edge must start and terminate at a node
Areas bounded by a set of edges and nodes are called regions
When counting regions, include the area outside the graph as a
region, too
Flow Chart Flow Graph
INDEPENDENT PROGRAM PATHS
Defined as a path through the program from the start node until
the end node that introduces at least one new set of processing
statements or a new condition (i.e., new nodes)
Must move along at least one edge that has not been traversed
before by a previous path
Basis set for flow graph on previous slide
Path 1: 1-11
Path 2: 1-2-3-4-5-10-1-11
Path 3: 1-2-3-6-8-9-10-1-11
Path 4: 1-2-3-6-7-9-10-1-11
The number of paths in the basis set is determined by the
cyclomatic complexity
CYCLOMATIC COMPLEXITY
Provides a quantitative measure of the logical complexity of a program
Defines the number of independent paths in the basis set
Provides an upper bound for the number of tests that must be conducted to
ensure all statements have been executed at least once
Can be computed three ways
1. The number of regions
2. V(G) = E – N + 2, where E is the number of edges and N is the number
of nodes in graph G
3. V(G) = P + 1, where P is the number of predicate nodes in the flow
graph G
Results in the following equations for the example flow graph
Number of regions = 4
V(G) = 14 edges – 12 nodes + 2 = 4
V(G) = 3 predicate nodes + 1 = 4
DERIVING THE BASIS SET AND TEST
CASES
1) Using the design or code as a foundation, draw a
corresponding flow graph
2) Determine the cyclomatic complexity of the resultant
flow graph
3) Determine a basis set of linearly independent paths
4) Prepare test cases that will force execution of each
path in the basis set
EXAMPLE
code Flow graph
CONDITION TESTING
exercises the logical conditions contained
in a program module.
Conditions:
a Boolean variable
a relational expression,
A compound condition (composed of two
or more simple conditions, boolean
operators, and parentheses)
CONDITION TESTING
types of errors in a condition:
Boolean operator errors (incorrect/missing/extra
Boolean operators),
Boolean variable errors,
Boolean parenthesis errors,
relational operator errors
arithmetic expression errors.
The condition testing method focuses on testing
each condition in the program to ensure that it
does not contain errors.
CONDITION COVERAGE
Condition coverage is a measure of
percentage of Boolean sub-expressions of
the program that have been evaluated as
both true or false outcome (applies to
compound predicate) in test cases.
Notice that in line 7 there are three sub-
Boolean expressions to the larger
statement (a==b),(c==d), and bug(a).
CONDITION COVERAGE
Condition coverage measures the outcome of
each of these sub-expressions independently
tested as both true and false.
CONDITION COVERAGE
CONDITION COVERAGE
LOOP TESTING - GENERAL
A white-box testing technique that focuses exclusively on
the validity of loop constructs
Four different classes of loops exist
Simple loops
Nested loops
Concatenated loops
Unstructured loops
LOOP TESTING - GENERAL
TESTING OF SIMPLE LOOPS
1) Skip the loop entirely
2) Only one pass through the loop
3) Two passes through the loop
4) m passes through the loop, where m < n
5) n –1, n, n + 1 passes through the loop
‘n’ is the maximum number of allowable passes through the
loop
TESTING OF NESTED LOOPS
1) Start at the innermost loop; set all other loops to minimum
values
2) Conduct simple loop tests for the innermost loop while holding
the outer loops at their minimum iteration parameter values; add
other tests for out-of-range or excluded values
3) Work outward, conducting tests for the next loop, but keeping all
other outer loops at minimum values and other nested loops to
“typical” values
4) Continue until all loops have been tested
TESTING OF CONCATENATED LOOPS
For independent loops, use the same approach
as for simple loops
Otherwise, use the approach applied for nested
loops
TESTING OF UNSTRUCTURED LOOPS
Redesign the code to reflect the use of structured
programming practices
Depending on the resultant design, apply testing for
simple loops, nested loops, or concatenated loops
DATA FLOW TESTING
The data flow testing method selects test paths of a
program according to the locations of definitions and
uses of variables in the program
a structural test technique which aims to execute
subpaths from points where each variable in a
component is defined to points where it is referenced.
DATA FLOW TESTING
These subpaths are known as definition-use pairs
(du-pairs).
The different data flow coverage criteria require
different du-pairs and subpaths to be executed.
Data flow testing is a powerful tool to detect improper
use of data values due to coding errors.
DATA FLOW TESTING
main()
{
int x;
if (x==42)
{ ...}
}
EXISTENCE POSSIBILITIES OF A VARIABLE
Variables that contain data values have a
defined life cycle. They are created, they
are used, and they are killed
Three possibilities exist for the first occurrence
of a variable through a program path:
~d: the variable does not exist (indicated by the ~),
then it is defined
~u: the variable does not exist, then it is used (u)
~k: the variable does not exist, then it is killed or
destroyed (k)
EXISTENCE POSSIBILITIES OF A VARIABLE
The first is correct. The variable does not exist and then
it is defined.
The second is incorrect. A variable must not be used
before it is defined.
The third is incorrect. Destroying a variable before it is
created is indicative of a programming error.
SEQUENCE OF POSSIBILITIES
dd: Defined and defined again-not invalid but suspicious.
Probably a programming error.
du: Defined and used-perfectly correct. The normal case.
dk: Defined and then killed-not invalid but probably a
programming error.
uu: Used and used again-acceptable.
uk: Used and killed-acceptable.
kd: Killed and defined-acceptable. A variable is killed and then
redefined.
ku: Killed and used-a serious defect. Using a variable that
does not exist or is undefined is always an error.
kk: Killed and killed-probably a programming error.
REFERENCE
“Testing Conventional Applications” ,
chapter 18 from “Software Engineering, A
Practitioners approach, 7th edition”.