ST Lec6
ST Lec6
LECTURE # 6
STRUCTURAL TESTING
ü Email: [email protected]
ü Website: http://fms.uettaxila.edu.pk/Profile/ali.javed
ü Research Lab: http://msplab.uettaxila.edu.pk
ü Contact No: +92-51-9047747
ü Office hours:
n Monday, 11:00 - 12:00, Office # 7 S.E.D
q Coverage Types
q Examples
ü After this, the code to be tested is identified, and test cases are created
for the test that is specific to path or condition
q Statement coverage
ü Statement coverage is a measure of the percentage of statements that
have been executed by test cases. Your objective should be to achieve
100% statement coverage through your testing.
q Method coverage
ü Method coverage is a measure of the percentage of methods that have
been executed by test cases. Undoubtedly, your tests should call 100%
of your methods.
ü Method coverage of 50%, for example, means that half of the methods
have been called [1]
q Branch coverage
ü Branch coverage is a measure of the percentage of the decision points
(Boolean expressions) of the program have been evaluated as both
Dr. Ali Javed true and false in test cases.
Structural Testing Categories
8
q Path coverage
ü Path coverage refers to designing test cases such that all linearly
independent paths in the program are executed at least once.
printf("Enter an integer:");
scanf("%d", &x);
pos = 0;
even = 0;
if (x > 0) {pos = 1;}
if (x%2 == 0) {even = 1;}
printf ("%d, %d, %d\n", x, pos, even);
q
return 0;
}
Printf() X>0 T
Pos=1
F
Scanf()
X%2=0 T Even = 1
Pos=0
F
Even=0 Printf()
End
Dr. Ali Javed
Structural Testing and Flowcharts
11
q If test suite executes all statements, then test suite visits every box and
diamond in the flowchart
q We say the test suite covers every node
q We can also say the test suite covers every statement
q This does not mean that every arrow (edge) in the flowchart has been
followed
q If every arrow in the flowchart has been taken by some case in the test suite:
q We say the test suite covers every edge
q We can also say the test suite covers every decision
Printf() T
x>0 Pos=1
Coding F
mistake made Scanf()
by a novice
programmer x%2=0 T Even = 1
(initialized
incorrectly)
Pos=1
F
Even=1 Printf()
End
Dr. Ali Javed
Would 100% Statement/Node Coverage Find
the Mistake with test case x=2?
14
q “Line Coverage”:
q Any line containing code is measured
q Considered covered if any code on the line is executed
q Not exactly the same thing as statement coverage
q Can have more than one statement on a line
q try: if sam[0] != 'harry': print('hellp', sam)
q except:pass
Line
i = 0; i=0
while (s[i] != 0) {
if (s[i] >= ‘a’) && (s[i] <= ‘z’))
{
s[i]=s[i] – 32;
}
F s[i]!=0?
i++;
} T
s[i]>=‘a’&&
F s[i]<=‘z’?
T
s[i]=s[i]-32
i++
q This test case also follows both arrows from the top diamond
q This is because:
q First time through loop (i==0), T branch taken
q Next time condition is evaluated (i==1), s[i] is the null (end of string)
character
q Hence, F branch is also taken
q We should always define precisely what we mean by minimality for a given test
suite
q Here, makes more sense to accept (B) as minimal
q Don’t’ have to run program as many times, incur overhead of starting up
process again
q Decision: the whole thing in parentheses after the “if”, while”, etc
q Consider the code:
if ((c>=‘a’) && (c<=‘z’)) {..}
q (c >=‘a’) && (c<=‘z’) is the decision
q Example:
q Instead of writing s[i]>=‘a’
&&
s[i]<=‘z’
F
T
s[i]>=‘a’
q we write F
T
s[i]<=‘z’
F T
q Now we have two new arrows
q To cover all arrows, we have to cover the two ones as well
q A false
q A true
Path (strongest)
SC Condition
Edge
(Decision)
Node
(Statement)
Line (weakest)
Dr. Ali Javed Where arrow from A to B means “B is stronger than A”
Path Coverage: Basic path testing
29
q Basis path testing (McCabe, 1976) is a means for ensuring that all independent paths through
a code module have been tested.
q An independent path is any path through the code that introduces at least one new set of
processing statements or a new condition. (Pressman, 2001)
q Basis path testing provides a minimum, lower-bound on the number of test cases that need to
be written.
path 1: 1-2-4-5-6-7 4
path 2: 1-2-4-7 e
path 3: 1-2-3-2-4-5-6-7 i 5 g
path 4: 1-2-4-5-6-5-6-7 f region
Step 4: Prepare test cases that will force execution of each 6
path in the basis set.
h
Step 5: Run the test cases and check their results
7
q Consider Test Case 1: the method call foo(0, 0, 0, 0, 0.), expected return value of
0.
q If you look at the code, you see that if a has a value of 0, it doesn’t matter what the
values of the other parameters are – so we’ll make it really easy and make them
all 0. Through this one call we attain 100% method coverage.
q As a result, we had 42% (5/12) statement coverage from Test Case 1. We can attain
100% statement coverage by one additional test case,
q Test Case 2: the method call foo(1, 1, 1, 1, 1.), expected return value of 1. With this
method call, we have achieved 100% statement coverage because we have now
executed the program statements on lines 6-12.
q We need to ensure that each of these predicates (compound or single) is tested as both
true and false. Table 1 shows our progress so far:
q Therefore, we currently have executed three of the four necessary conditions; we have achieved 75% branch
coverage thus far.
q We add Test Case 3 to bring us to 100% branch coverage: foo(1, 2, 1, 2, 1). When we look at the code to
calculate an expected return value, we realize that this test case uncovers a previously undetected division-by-zero
problem on line 10!
q In many cases, the objective is to achieve 100% branch coverage in your testing, though in large systems only 75%-
85% is practical. Only 50% branch coverage is practical in very large systems of 10 million source lines of code or
more (Beizer, 1990).
q Condition coverage measures the outcome of each of these sub-expressions independently tested
as both true and false. We consider our progress thus far in Table 2.
q Write Test Case 4 to address test (c==d) as true: foo(1, 2, 1, 1, 1), expected return value 1.
q However, when we actually run the test case, the function bug(a) actually returns false, which causes our
actual return value (division by zero) to not match our expected return value. This allows us to detect an
error in the bug method. Without the addition of condition coverage, this error would not have been
revealed.
q To finalize our condition coverage, we must force bug(a) to be false. We again examine our bug()
information, which informs us that the bug method should return a false value if fed any integer greater
than 1. So, we create Test Case 5, foo(3, 2, 1, 1, 1), expected return value “division by error”. The
condition coverage thus far is shown in Table 3
[1] http://docs.ncover.com/best-practices/code-quality-metrics/