You are on page 1of 49

White-Box Testing Techniques

Testing Techniques

1. Dynamic Testing
1. Black-Box
2. White-Box
2. Static Testing
3. Validation Testing
4. Regression Testing
White-Box Testing
• It is another dynamic testing technique
• It is also called “structural” or “development” testing as it
is mainly used by developers to test the entire design,
structure and code of software. Here, the term software
structure refers to the logic of the program.
• It is also known as “glass-box testing because everything
required to implement the software is visible.
• White-box testing ensures that all the internal parts of
the software are adequately tested

• ( In this chapter, we discuss three techniques :

• Basis Path Testing,


• Data flow Testing ( static & dynamic ),
• Mutation Testing )
Need of White-box Testing
• White-box testing is the initial stage of testing of modules and
black-box testing is the second stage.
• Black-box testing cannot be executed until the code is
produced and checked using white-box testing techniques. So
white-box testing is essential.
• There are categories of bugs that can be revealed by white-box
testing and not by black-box testing. So it is necessary.
• Design phase errors will be reflected in code. So white-box
testing must be done for code verification ( unit verification)
• White-box testing explores all logical paths which are
commonly as well as rarely executing.
• White-box testing helps to detect typographical errors which
are not covered by black-box testing.
Logic Coverage Criteria
• Test cases for structural testing are
designed based on logic of the program.
• Every element of the logic must be covered
by the test cases.
• Basic forms of logic coverage are :
• o Statement coverage
• o Decision or Branch coverage
• o Condition coverage
• o Decision/Condition coverage
• o Multiple Condition Coverage
Statement coverage
• In this form, test cases are designed to
cover ( or execute ) all statements in the
module under testing.
• For example, Consider the following
sample code,
Statement coverage
• The following test cases are enough for statement
coverage. These test cases will cover every
statement in the code segment. But these test
cases are not enough to test all conditions and
paths exists in the code and errors might exist
undetected.

• Test Case 3 : x = y, is also needed to execute the


path of skipping the loop and directly jump to printf
statement.
• Statement coverage is necessary but not a sufficient
criteria
Decision or Branch coverage
• In this form, test cases are designed to
include all possible outcomes of each
decision at least once.
• In other words, each branch path must be
executed at least once
• Example:
– In the sample code mentioned above, the
following test cases will consider all possible
outcomes by while and if conditions
Condition coverage
• In this form, each condition in a decision
will take all possible outcomes at least
once
• Example:
• Consider the while condition :
• while ( I <= 5 && ( J < Count ) )
• Here the following test cases are enough
to cover both conditions
Decision/Condition coverage
• Condition coverage does not ensure the coverage of decisions.
• Consider the following decision
– if ( A && B) , test cases for condition coverage are :

– But these two test cases will not execute the THEN clause
of if statement
• So, decision / condition coverage considers all possible
outcomes of each condition at least once and all possible
outcomes of each decision at least once
• There for test cases can be designed as follows to cover both
conditions and decision
Multiple Condition Coverage
• Multiple condition coverage requires that ,
we should design sufficient test cases such
that all possible combinations of condition
outcomes in each decision and all point of
entry are invoked at least once
• • Example :
– For the decision if ( A && B ) ,the following test
cases can be designed :
White box testing techniques
1. Basis path testing
2. Data flow Testing ( Static data flow
testing & Dynamic data flow testing )
3. Mutation Testing
Basis path testing
• Basis path testing is the oldest structural testing
technique
• It is based on control structure of the program
• Basis path testing is the technique of selecting the
paths that provide a basis set of execution paths
through the program.
• A flow graph is prepared covering all possible paths
and executed during testing
• Path coverage is useful for detecting more errors
• Disadvantage of path coverage criteria is that
programs with loops may have infinite number of
possible paths, all of which are not practical to test
Basis path testing
• Guidelines for effectiveness of path testing
• Control flow Graph ( Decision-to-Decision
graph, DD Graph )
• Path Testing Terms
• Cyclomatic Complexity
• Steps ( Guidelines ) for Basis Path Testing
• Applications of Path Testing
Basis path testing
Guidelines for effectiveness of path testing :
• Path testing is based on control structure for
which flow graph is prepared
• Path testing requires complete knowledge of the
program’s structure or logic
• Path testing is closer to the developer and used by
him to test his module
• As the size of the software under test ( SUT )
increases, the effectiveness of path testing will be
reduced
• Choose enough paths to get maximum logic
coverage
Basis path testing
Control flow Graph ( Decision-to-Decision graph, DD Graph ) :
• It is a graphical representation of control structure of a program
• It is a directed graph (V,E)
• Where
• V = set of vertices and
• E = set of edges ( ordered pairs of elements of V )
• Flow graph notations
1) Node
– Numbered or labeled circles representing one or more procedural statements
2) Edges or links
–Lines with an arrow representing the flow of controls. An edge must terminate at
a node.
3) Decision node
–A node with more than on arrow leaving it is called a decision node
4) Junction node
– A node with more than one arrow entering it is called a junction node
5) Regions
– Area bounded by edges & nodes are called regions. Area outside the graph is also
considered as a region
• Flow graph Notations for different programming constructs
Basis path testing
Basis path testing
Path Testing Terms :
1) Path
– Sequence of instructions or statements that starts at an entry, junction or
decision and ends at another, or possibly the same , junction, decision or exit
2) Segment
– Paths are formed by several segments. Smallest segment is a link ( a single
process that lies between two nodes )
– Examples :
• Junction – process – junction
• Junction – process – decision
• Decision – process - junction
• Decision – process – decision
3) Path Segment
– It is a succession of consecutive links that belongs to same path
4) Length of a path
– No. of links in it. An alternative way to measure length of path is count the nodes
traversed. ( If there is entry and exit nodes, then Length = No. of nodes – 1 )
5) Independent Path
– An independent path consists of at least one new edge. The new edge or link
introduces a new set of instructions for processing
Basis path testing
Cyclomatic Complexity:
• It is a numeric measurement that shows the
logical complexity of a program defined by
McCabe
• It can be calculated by considering the control
flow graph.
• The significance of cyclomatic complexity with
basis path testing is that the complexity number
actually represents the number of independent
paths in the control structure of the program
Basis path testing
• Consider the following sample graph

• There are six possible paths in the graph, out of


which only four are independent paths
• • Possible paths : acei, acgh, acfj, bdfj, bdgh, bdei
• • Independent paths ( must contain at least one
new edge ) : acei, acgh, acfj, bdgh
Basis path testing
Formulation of cycomatic complexity :
• For a strongly connected graph,
– Cyclomatic Complexity Number V(G) = e – n + 1 ,
– where
– e = number of edges and
– n = number of nodes
• For graphs which are not strongly connected, add one
more edge from last to first.
– So, V(G) = e – n + 2
– Example : for the above sample graph
– V(G) = 10 – 8 + 2 = 4 ( no. of independent paths)
• o By Miller’s theorem,
– V(G) = d + 1, where
– d is the number of decision nodes
– for, k – way decision, d = k – 1
• Example: for the above sample graph
– V(G) = d + 1 = (1 + 2) + 1 = 4
– ( Graph has one , 2-WAY & one , 3-WAY decisions )
Basis path testing
• If a program contain several procedures, each
procedure can be represented as a separate
graph. Therefore,
– V(G) = e – n + 2p,
– where
– p is the number of graphs ( procedures )
– e & n are edges and nodes of the whole graph Miller’s theorem
becomes :
– V(G) = d + p
Basis path testing
Steps ( Guidelines ) for Basis Path Testing:
• The following steps should be followed to design
test cases using basis path testing
– 1) Draw the flow graph of the code to be tested
– 2) Determine the cyclomatic complexity of the flow
graph
– 3) Cyclomatic complexity provides the number of
independent paths. Determine a basis set of
independent paths through the program control
structure.
– 4) The basis set determined in step 3 is the basis for
designing test cases. Choose data based on each
independent path in order to execute the path
Basis path testing
• Example
• Consider the program segment ,
Basis path testing
• Solution :
• 1) DD Graph
Basis path testing
• 2) Cyclomatic Complexity
– • V(G) = e – n + 2p
– = 10 - 8 + 2 * 1
– = 4
– • V(G) = d + p
– = 3 + 1 =4
– V(G) = No. of regions = 4

• 3) Independent paths
– •A–B–F–H
– •A–B–F–G–H
– • A – B- C – E – B – F – G – H
– •A–B–C–D–F-H

• 4) Test Cases designed


Basis path testing
Applications of Path Testing :

1) Thorough Test / More Coverage


• • Path testing provides us best code coverage, leading to a thorough testing.
Basis path set provides the number of test cases to be executed for full
coverage.
2) Unit Testing
• • Path testing is mainly used for structural testing of a module. Path testing
uncovers errors in decision outcomes and prepare each module for integration
3) Integration Testing
• • Path testing analyses all the paths on the interface and explores all possible
errors that can occur while calling other modules
4) Maintenance Testing
• • Path testing is also necessary with modified versions of the software
5) Testing effort is proportional to Complexity of software
• • Path testing takes care of the complexity of the software and derives the
number of tests to be carried out.
6) Basis path testing is concentrated on error-prone software
• • Cyclomatic complexity number ( no. of test cases needed ) signifies that the
testing effort is only on the error-prone part of the software, thus minimizing the
testing effort.
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
• Data and data integrity are as important as
code and code integrity of a module
• • Data flow testing is a white-box testing
technique that can be used to detect improper
use of data values due to coding errors
• • An example for data error is, define a variable
and use it in a predicate without initializing it.
• • Data flow testing allows to find out
inappropriate data definitions , their use in
predicates and computations and their
terminations.
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
States of Data Objects
• A data objects can be in the following states:
• Defined (d) : A data object is defined when it is
initialized ( when it is on left side of an assignment
statement), opening files, dynamically allocated etc.
• Killed/ undefined/Released (k) : Re-initializations,
exiting a loop which finishes the scope of loop control
variable, dynamically releasing memory, closing files
etc. are considered as killing / releasing / undefining
• Usage (u) : Use in expressions or right hand side of
assignments, conditions or predicates etc. Usage is
either Computational use ( C-use) or Predicate use
(PUse)
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
• Data Flow Anomalies
• Anomalies represent pattern of usage that
may lead to an incorrect execution of code
• o Data flow anomaly is denoted by a two
character sequence of actions like :
• dk, ku, dd, kk etc.
• There are 9 possible two character
combinations, out of which 4 are anomalies
(See table below).
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
• It is also possible to represent data
anomalies as single character pattern by
using
• following notations :
~x - all prior actions are not of interested to x
x~ - all post actions are not interested to x
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
Data flow testing terminologies
• Suppose P is a program, G(P) is its graph and V is a set of variables
• o Definition Node : Nodes corresponds to definition of a variable i.e.
assigning values to a variable Eg:- i/p statements , procedure call,
assignement statement etc.
• o Usage Node : A node corresponds to a statement in which a variable is
used in a computation or conditions. Usage node can be :
– • Predicate usage node or
–• Computation usage node
• o Loop-free path segment: It is a path segment for which every node is
visited once at most
• o Simple-path segment A path segment in which at most one node is visited
twice ( loop-free path or loop with only one node )
• o du-path ( Definition-use path) A du-path with respect to a variable v is a
path between its definition and the usage node
• o dc-path ( Definition-clear path) A dc-path with respect to a variable v is a
path between definition node and usage node such that no other node in the
path is a defining node of variable v. du–paths which are definition clear are
easy to test in comparision to du-paths which are not dc-paths
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
• Static Data flow Testing
• Here, source code is analyzed without executing it.
• o Consider an example of an application given below :
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
• It is not always possible to determine the
state of a variable by static analysis of the
code.
• So all anomalies cannot be determined
using static analysis.
• So static analysis is not enough
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
Dynamic Data flow Testing
• Dynamic data flow testing is performed
with the intention to uncover possible bugs
in data usage during execution of the code.
• o Test cases are designed in such a way
that :
• Every definition of data variable is traced to
each of its use
• Every use is traced to each of its definition
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
Various strategies used to design test cases are as follows :
• All-du Paths (ADUP)
• • It is the strongest data flow testing strategy, since it is a superset of all other data flow testing
strategies
• • It states that every du-path from every definition of every variable to every use of that definition
should be executed under some test.
• All-uses ( AU)
• • This states that for every use of the variable, there is a path from the definition of that variable to
the use.
• All-p-uses/some c-uses (APU+C)
• • This strategy states that for every definition of every variable, include one dc-path from the
definition to every predicate use.
• If there are definition with no p-use following it, then add computational use ( c-use) test cases as
required to cover every definition
• All c-uses/Some p-uses (ACU+P)
• • This strategy states that for every definition of every variable, include one dc-path from the
definition to every computational use (c-use).
• If there are definition with no c-use following it, then add predicate use ( p-use) test cases as required
to cover every definition
• All-Predicate-Uses (APU)
• • It is derived from APU+C strategy and states that for every variable,
• there is a path from every definition to every p-use of that definition
• All-Computational-Uses (ACU)
• • It is derived from ACU+P strategy and states that for every variable, there is a path from every
definition to every c-use of that definition.
• All-Definitions (AD)
• • It states that every definition of every variable should be covered by at least one use of that variable
( computation or predicate )
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
• Steps for Dynamic data flow testing
• Draw the program flow graph
• o Find the data flow graph of each variable
• o Prepare the table for Definition/Use status of all
variables
• o Find all du-paths
• o Identify du-paths that are not dc-paths
• Generate test cases to test all du-paths at least
once.
• If we cannot test all du-paths, we have to test all
du-paths that are not dc-path.
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
Ordering of data flow testing strategies
• While selecting a test case, we need to
analyze the relative strength of various
data flow testing strategies.
Data flow Testing - ( Static data flow
testing & Dynamic data flow testing )
• Figure above shows the order of their
relative strength.
• Strength of testing strategies reduces
along the direction of arrows
• o APDU is the strongest criteria for
selecting test cases
Mutation Testing
• Mutation testing is the process of mutating some
segment of code ( putting some error in the code ) and
then testing this mutated code with some test data.
• During testing, many versions of the program will be
created, by introducing one fault to each.
• Test data is used to execute these fault versions of the
program
• Faulty programs are called Mutants of the original
program and a mutant is said to be killed when a test
case causes it to fail. When this happens, the mutant
is considered dead and no longer needs to remain in
the testing process
• The main objective of testing is to select efficient test
data which have error detection power.
• The criterion for this test data is to differentiate the
original program from the mutant.
Mutation Testing
• There are two types of mutants:
Primary Mutants
• When the mutants are single modifications
of the initial program using some operators,
they are called primary mutants
Secondary Mutants
• When multiple levels of mutation are
applied on the initial program, those mutants
are called secondary mutants.
Mutation Testing
Primary Mutants
• When the mutants are single modifications of the
initial program using some operators, they are
called primary mutants.
• Consider the following c-program to understand
primary mutants :

• We can consider the following primary mutants


for the above example :
• M1 : x = x – y; M2 : x = x / y;
• M3 : x = x + 1; M4 : printf( “%d”, y);
Mutation Testing
• The results of the initial program and its
mutants are shown below :
Mutation Testing
Secondary Mutants
• When multiple levels of mutation are applied
on the initial program, those mutants are
called secondary mutants.
• Consider the following original c-program
code
if ( a < b )
c = a;
• Following are some of its secondary
mutants.
Mutation Testing
Mutation Testing Process
• Construct the mutants of a test program
• Add test cases to the mutation system and check the output of
the original program on each test case to see if it is correct
• If the output of original program is incorrect, a fault has been
found and the program must be modified and restart the process
• If the output is correct, that test case is executed against each
live mutant
• If the output of the mutant differs from that of the original
program on the same test case, the mutant is assumed killed
• After executing all test cases, the remaining live mutants belongs
to one of two categories :
o Mutants which are functionally equivalent to the original
program so that they cannot be killed
o Killable mutants, but test cases are not sufficient to kill them.
• Mutation score of a set of test data is the percentage of non-
equivalent mutants killed by the test data.. If score is 100%, then
test data is called mutation-adequate
Mutation Testing
• Example :
Mutation Testing
• Selected Test Data

• M1 & M3 are not killed by the selected test data. Therefore the test
data is incomplete. So, we need to
add a new test data TD4 = { 2, 2,1 }, this test data will kill M3.
M1 is equivalent to original program P

You might also like