week3_solutions

advertisement
Tutorial 3, Q1 Answers
Consider the following simple program (in no particular language) to find the
smallest prime factor of a number:
smallest(int p) /* precondition p > 1 */ a)
{
int q = 2;
while(p mod q > 0 AND q < sqrt(p) ) b)
q := q+1
;
if (p mod q = 0)
then
print(q,''is the smallest factor'')
else
print(p, ``is prime'')
;
}
Draw the control for this program
and (if it helps) the structural treeform of this program.
Calculate:
–
number of nodes
–
number of edges
–
number of simple paths
–
all paths with k=2
Program
smallest(int p) (*p>1*)
{
int q = 2;
while(p mod q > 0
AND
q < sqrt p)
do
q := q+1
;
if (p mod q = 0)
then
print(q,’is factor’)
else
print(p,’is prime’)
;
}
Tree
CFG
1
S
2
3
4
A1
S
A2
S
5
6
L3
C5
7
8
A4
A6
A7
S8
A2
Number of Nodes:
S7
• FA() = 2
• Fs(m1,m2) = m1 + m2 - 1
A2
S6
• FC(m1,m2) = m1 + m2
• FL(m1) = m1 + 1
L3
A2
C4
A2
A2
S9
A1
Number of Edges:
S8
• FA() = 1
• Fs(m1,m2) = m1 + m2
A1
S7
• FC(m1,m2) = m1 + m2 +2
• FL(m1) = m1 + 2
L3
A1
C4
A1
A1
Number of simple paths
A simple path is one in which no edge
is traversed more than once
S4
A1
•
•
•
•
S4
A1
S4
L2
A1
C2
A1
A1
nsp(A) = 1
nsp(S(P1,P2)) = nsp(P1) x nsp(P2)
nsp(C(P1,P2)) = nsp(P1) + nsp(P2)
nsp(L(P1)) = nsp(P1)+1
Number of All Paths (k=2)
• ap(A) = 1
• ap(S(P1,P2)) = ap(P1) x ap(P2)
• ap(C(P1,P2)) = ap(P1) + ap(P2)
• ap(L(P1)) = ap(P1)2+ ap(P1)+ 1
S6
A1
S6
A1
S6
L3
A1
C2
A1
A1
Tutorial 3, Q2
Consider the following simple program (in no particular language) to find the
smallest prime factor of a number:
smallest(int p) /* precondition p > 1 */
{
int q = 2;
while(p mod q > 0 AND q < sqrt(p) )
q := q+1
;
if (p mod q = 0)
then
print(q,''is the smallest factor'')
else
print(p, ``is prime'')
;
}
a)
Draw the control for this
program and annotate the nodes
to indicate the definitions/uses
of variables p and q.
b)
Label the nodes and give All
DU Paths for p and q.
c)
Give a test suite which gives
100% coverage for All DU
paths.
d)
Which of these paths are
required for: AU, APU+C,
ACU+P, APU, ACU, and AD
coverage.
e)
Explain whether or not the “all
predicate uses" test set is
sufficient for branch coverage
of this program?
Program
smallest(int p) (*p>1*)
{
int q = 2;
while(p mod q > 0
AND
q < sqrt p)
do
q := q+1
;
if (p mod q = 0)
then
print(q,’is factor’)
else
print(p,’is prime’)
;
}
Usage
CFG
p
1
d
up
4
5
6
7
8
up
uc,d
up
up
uc
uc
paths
For p
d
2
3
q
All DU
123
12343
1235
123435
12357
1234357
For q
23
234
235
2356
43
434
435
4356
Required
paths
p
123
12343
1235
123435
12357
1234357
q
23
234
235
2356
43
434
435
4356
Test
Actual path Test Output
Input
p=3
p=5
123578
12343578
3 is prime
5 is prime
Badly drawn wiggly line
indicates paths which
subsume other paths
P=2
123568
2 is factor
P=11
1234343578
11 is prime
p=9
12343568
3 is factor
Other coverages:
So to cover all du paths we need to have 5 test cases: p=3 and p=5 and p = 2, p=9 and p=11.
Now to cover AU, we need only execute a single du path between each pair (d,u) that starts at a definition, d and ends
at a use, u. However, we need to ensure that we have done this for both variables in the program. Let’s consider
the variable p first. Of the du paths, we have 123 and 12343, but both these exercise the same pair (1,3) so just
123 will do. Also we don’t need both 1235 and 123435, just 1235 would do. Finally, we don’t need 12357 and
1234357, just 12357 will do. In conclusion, we see that we only need 12357 to cover all uses of the variable p.
There is only one definition of the variable p (at node 1) and the case which passes through 12357 hits all three
uses of the variable p at 3, 5, and 7. Therefore, to cover all uses of the variable p, we need only execute 123578
(p=3).
Notice how all du paths requires us (in this case) to go through the loop, whereas (for the variable p) AU does not. That
is because there was a choice of du paths for each du pair, where one went through the loop and one did not.
However, AU will force us to go through loops if the only du path from a definition to a use goes through a
loop. This is the case with the variable q in this example, as we shall see.
Let’s look at the AU criterion for the variable q. To understand the difference between All du paths coverage and AU
coverage, we need to be clear in our mind about the distinction between a du path and a du pair. The start and
end node of a DU path is a Definition and a Use respectively. The definition and use, together, form a du pair.
We notice that the 8 du paths identified for q all have different du pairs. That is, there are 8 distinct du pairs for
q, each of which corresponds to one of the du paths. This means that covering all uses of q will be the same as
covering all du paths for q. Therefore we need the same three test inputs to achieve this.
•For APU, we do not need to cover the computational uses of variables, but we must cover
the predicate uses. Therefore, we could choose the same three test cases that we chose for
AU, but this would be wasteful; we can manage with only two test cases for APU. I will
show you how. Notice that, for variable q, we still need to cover the pair (2,5) without
passing through 4 and also the pair (4,5), so we must have at least two test cases. However,
because we do not need to also cover node 6 (the computational use of the variable q), we
can use the path 123578 to cover the pair (2,5) for the variable q. This case, 123578, will
also cover all predicate uses of the variable p. So now we only need add a case for the
pairs (4,3) and (4,5). Either of 12343568 (p=9) or 12343578 (p=5) would do.
•For ACU, we need to cover the computational use of the variable p. In fact, every test
case that goes through node 7 does this. However, we need to cover all computational uses
of the variable q also. To do this we need to go through node 6. Clearly this cannot re-use
the test case for the variable p, since that has to go through node 7 and we cannot go
through both nodes 7 and node 6 in the same test case. Now, for variable q, there are two
definitions that reach the computational use at node 6, these are the definitions at nodes 2
and 4. The last criterion is easy:
•For AD, we need only hit all definitions of all variables that reach some use (of any kind –
either predicate or computation). These occur at nodes 1,2 and 4, so any test case that goes
through all three nodes will do. We could choose, 12343578 (p=5) for example.
APU versus Branch Cover
All predicate uses (as defined in the lecture) is not sufficient
for branch coverage as it only requires each predicate to
be tested in one direction, whereas branch coverage
requires each predicate to be taken in both directions.
For this program, as there are no predicates inside the body
of the loop, 100% APU coverage is possible without
entering the loop, whilst branch cover requires loop
body to be executed.
Download