0% found this document useful (0 votes)
0 views54 pages

Lecture(Whitebox testing) software engineering

The document discusses White Box Testing, also known as Glass Box Testing, which involves testing the internal structures or workings of an application. It outlines the advantages and disadvantages of this testing method, various code coverage types, and different testing methods such as control flow testing and cyclomatic complexity. Additionally, it provides an overview of how to implement basic path testing and the significance of graph matrices in evaluating program control structure during testing.

Uploaded by

mamshad567
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
0 views54 pages

Lecture(Whitebox testing) software engineering

The document discusses White Box Testing, also known as Glass Box Testing, which involves testing the internal structures or workings of an application. It outlines the advantages and disadvantages of this testing method, various code coverage types, and different testing methods such as control flow testing and cyclomatic complexity. Additionally, it provides an overview of how to implement basic path testing and the significance of graph matrices in evaluating program control structure during testing.

Uploaded by

mamshad567
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 54

SOFTWARE TESTING

LECTURE # 6

White Box Testing


Or
Glass Box Testing
Presentation Outline

-White Box Testing

- Advantages of White Box testing

- Disadvantages of White Box testing

- Code Coverage Types

- White Box Testing methods

All Rights Reserved


White Box Testing

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:

Guarantee that all independent paths within a module have been


exercised at least once.

Exercise all logical conditions 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.


Advantages of White Box Testing

i) As the knowledge of internal coding structure is prerequisite, it


becomes very easy to find out which type of input/data can help in
testing the application effectively.

ii) The other advantage of white box testing is that it helps in


optimizing the code
Disadvantages of White Box Testing

i) As knowledge of code and internal structure is a prerequisite, a


skilled tester is needed to carry out this type of testing, which
increases the cost.

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

• This testing approach identifies the


execution paths through a module of
program code and then creates and executes
test cases to cover those paths.
• Pick enough paths to assure that every
source statement is executed at least once.
• Path: A sequence of statement execution that
begins at an entry and ends at an exit.
Program Flow Graph (Control Flow Diagram)
A simple notation for the representation of control flow is called a flow graph
(or program graph).

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.

Areas bounded by edges and nodes are called regions.

A compound condition occurs when one or more Boolean operators is present


in a conditional statement

Each node that contains a condition is called a predicate node & is


characterized by two or more edges emanating from it.
Process Block
• A process block is a sequence of program statements that
execute sequentially from beginning to end.
• Once the block is initiated, every statement within it will be
executed sequentially.
• Process blocks are represented in control flow graphs by a
bubble with one or more entries and one exit.
Decision Point
• A decision point is a point in the module at which the
control flow can change.
• Most decision points are binary and are implemented by if-
then-else statements.
• Multi-way decision points are implemented by case
statements.
• They are represented by a bubble with one entry and
multiple exits.
Junction Point
• A junction point is a point at which control flows join
together.
Path
• A path through a program is a sequence of statements that starts at
an entry, junction, or decision and ends at another (possible the
same), junction, decision, or exit.
• A path may go through several junctions, processes, or decisions,
one or more times.
• Paths consist of segments.
• The length of a path is the number of links in a path.
Program Flow Graph (Control Flow Diagram)

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.

Code Coverage is defined by the following seven types.

1. Statement Coverage

2. Segment Coverage

3. Branch Coverage

4. Compound Condition Coverage

5. Basis Path Testing

6. Data Flow Testing

7. Loop Testing
Code Coverage

Code coverage is a measure used in software testing. It describes the degree


to which the source code of a program has been tested.

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.

Compound Condition Coverage:


When there are multiple conditions, you must test not only each
direction but also each possible combinations of conditions, which is usually
done by using a ‘Truth Table’.
Code Coverage Types

Basis Path Testing:


Each independent path through the code is taken in a pre-
determined order.

Data Flow Testing (DFT):


In this approach you track the specific variables through each
possible calculation, thus defining the set of intermediate paths through the
code.

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)

Any problems with this example?

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

• Consider test cases


– {(x=5,y=5), (x=5, y=-5)}
• The test suite is adequate for branch
coverage, but does not reveal the fault at
statement 6
• Predicate 4 can be true or false
operating on only one condition
⇒ Basic condition coverage

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.

Three ways to compute cyclomatic complexity:

- The number of regions of the flow graph correspond to the cyclomatic


complexity.

- Cyclomatic complexity, V(G), for a flow graph G is defined as


V(G) = E - N +2

where E is the number of flow graph edges and N is the number of flow graph
nodes.

- Cyclomatic complexity, V(G) = P + 1

where P is the number of predicate nodes contained in the flow graph G.


An Example

1 node
No. of regions = 4
(considering the universal region)
edge 2 3
No. of edges = 9
4 No. of nodes = 7

No. of predicate nodes = 3


5
region V(G) = 3 + 1 = 4

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

Graph Matrix is nothing more than a tabular representation of a flow graph.


However by adding a link weight to each matrix entry, the graph matrix
can become a powerful tool for evaluating program control structure
during testing.

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).

Representing in this form, the graph matrix is called a connection matrix.

Each row with two or more entries represents a predicate node.

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):

- First proposed by Tom McCabe.


- Used as a guide for defining a basis set of execution path.
- Guarantee to execute every statement in the program at least one time.

Step 1 : Using the design or code as a foundation, draw a corresponding


flow graph.

Step 2: Determine the cyclomatic complexity of the resultant flow graph.

Step 3: Determine a minimum basis set of linearly independent paths.


For example,
path 1: 1-2-4-5-6-7
path 2: 1-2-4-7
path 3: 1-2-3-2-4-5-6-7
path 4: 1-2-4-5-6-5-6-7

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

E1 < relational operator> E2

Where E1 and E2 are arithmetic expressions and < relational operator> is one
of the following: {<, , >, , =, }

A compound condition is composed of two or more simple conditions, Boolean


operators and parenthesis.

A condition without relational expression is referred to as a Boolean expression

Types of error in a condition includes the following:

Boolean operator error


Boolean variable error
Boolean parenthesis error
Relational operator error
Arithmetic expression error
Condition Testing Strategies
Two Condition testing strategies have been proposed here.

Branch testing is the simplest condition testing strategy. For a compound


condition C, the true and false branches of C and every simple condition
in C need to be executed at least once.

A B C A&B or C

TRUE TRUE TRUE TRUE


TRUE TRUE FALSE TRUE
TRUE FALSE TRUE TRUE
TRUE FALSE FALSE FALSE
FALSE TRUE TRUE TRUE
FALSE TRUE FALSE FALSE
FALSE FALSE TRUE TRUE
FALSE FALSE FALSE FALSE
Condition Testing Strategies
Domain testing is an important white box testing method. The goal is to
check values taken by a variable, a condition, or an index, and to prove
that they are outside the specified or valid range. It also contains
checking that the program acepts only valid input , because it is unlikely
to get reasonable results if idiocy has been entered. Colloquially, this part
can be called ``garbage in -- garbage out'' testing.

The following checks are suggested by M. Krüger and Glenford J. Myers

1. Have all variables used been initialized correctly?


2. Are all indices used to access an array inside the array's dimensions?
3. Are all those indices integers ?
4. Are all arguments in a comparison of the same type?
5. Are all boolean expressions correct? Check logical operands like AND, and
OR, and their priorities.

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.

For example, A pattern which indicates usage of data in a calculation after it


has been killed is certainly a bug which needs to be addressed.
Data Flow Testing
Data-flow Anomalies
Data-flow anomalies represent the patterns of data usage which may lead to
an incorrect execution of the code.

The notation for representing the patterns is :

• d – defined, created, initialized


• k – killed, terminated, undefined
• u – used
o c – used in a computation
o p – used in a predicate
• ~x - indicates all prior actions are not of interest to x
• x~ - indicates all post actions are not of interest to x
Data Flow Testing
Loop Testing

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 following set of tests can be applied to


simple loops, where n is the maximum
number of allowable passes through the
loop.

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.


Nested Loops
If we were to extend the test approach for simple
loops to nested loops the number of possible
tests would grow as the level of nesting
increases. Beizer suggest an approach that will
help to reduce the number of tests:

1. Start at the innermost loop. Set all other loops to


min. values

2. Conduct simple loop tests for the innermost loop


while holding the outer loops at their min.
iteration parameter values.

3. Work outward conducting tests for the next loop,


but keeping all other outer loops at min. values
and other nested loops to typical values.

4. Continue until all loops have been tested.


Concatenated Loops

Concatenated loops can be tested using


the approach defined for simple loops, if
each of the loops are independent of
the other. However if two loops are
concatenated and the loop counter for
loop 1 is used as a initial value for loop
2, then the loops are not independent.

When the loops are not independent,


the approach applied to nested loops is
recommended.
Unstructured Loops

Whenever possible, this class of loops


should be redesigned to reflect the
use of structured programming
concepts.
Unit Testing

Unit testing focuses on


verification effort on the
smallest unit of software design
(the software component or
module).

Using the component level


design description as a guide,
important control paths are
tested to uncover errors within
the boundary of the module.

The unit test is white box


oriented and the step can be
conducted in parallel for
multiple components.
Unit Test Considerations

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.

Finally all error handling paths are tested.

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.

In most applications a driver is nothing more than a “main program” that


accepts test case data, passes such data to the component to be tested and
prints relevant results.

Stubs serve to replace modules that are subordinate the component to be


tested. A stub or dummy subprogram uses the subordinate module’s
interface, may do minimal data manipulation, prints verification of entry,
and returns control to the module undergoing testing.

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

You might also like