Verificação e Validação de Software Departamento de Informática Faculdade de Ciências da Universidade de Lisboa
Eduardo Marques, Vasco Thudichum Vasconcelos
Logic-based test coverage Basic approach Clauses and predicates - - PowerPoint PPT Presentation
Logic-based test coverage Basic approach Clauses and predicates Basic coverage criteria: CC, PC, CoC Structural logic coverage of source code Logic coverage of specifications Active clause coverage criteria (GACC, CACC, RACC) Verificao e
Verificação e Validação de Software Departamento de Informática Faculdade de Ciências da Universidade de Lisboa
Eduardo Marques, Vasco Thudichum Vasconcelos
x > 10, f(y) = 30, and z are clauses
2
3
4
5
6
7
9
For p1 = x > y ⋀ (x = z-1 ⋁ x > z ) the clauses are: a: x > y b: x = z-1 c: x > z For p2 = z > 0 ⋁ z > x+y the clauses are: d: z > 0 e: z > x+y For P = {p1, p2} we have TR(PC) = {p1, ¬p1, p2, ¬p2} TR(CC) = {a, ¬a, b, ¬b, c, ¬c, d, ¬d, e, ¬e} TR(CoC) = {a⋀b⋀c, ¬a⋀b⋀c, a⋀¬b⋀c, a⋀b⋀¬c, ¬a⋀¬b⋀c, ¬a⋀b⋀¬c, a⋀¬b⋀¬c, ¬a⋀¬b⋀¬c, d⋀e, ¬d⋀e, d⋀¬e, ¬d⋀¬e} Exercise 1: Find combinations of values for x, y, z that will satisfy the test requirements of PC, CC and CoC in turn. Observe that there are infeasible requirements for CoC.
10
11
12
Note: the & | ^ ~ operators also correspond to logical operators. What are the differences between && and & , || and | ?
13
Logical expression Java expression a ⋀ b a && b a ⋁ b a || b ¬ a !a a → b !a || b a ↔ b a == b
a != b
public static int daysInMonth(int m, int y) { if (m <= 0 || m > 12) throw new IllegalArgumentException("Invalid month: " + m); if (m == 2) { if (y % 400 == 0 || y % 4 == 0 && y % 100 != 0) return 29; else return 28; } if (m <= 7) { if (m % 2 == 1) return 31; return 30; } if (m % 2 == 0) return 31; return 30; }
Predicates and clauses p1: c1 || c2, where c1: m <= 0; c2: m > 12 p2: c3, where c3: m == 2 p3: c4 || c5 && c6, where c4: y % 400 == 0; c5: y % 4 == 0; c6: y % 100 != 0 p4: c7, where c7: m <= 7 p5: c8, where c8: m % 2 == 1 p6: c9, where c9: m % 2 == 0
14
public static int daysInMonth(int m, int y) { if (m <= 0 || m > 12) // p1 …; if (m == 2) { // p2 if (y % 400 == 0 || y % 4 == 0 && y % 100 != 0) // p3 …; } … }
p r(p) p1 true p2 r(p1) && !p1 p3 r(p2) && p2
public static int daysInMonth(int m, int y) { if (m <= 0 || m > 12) // p1 …; if (m == 2) { // p2 if (y % 400 == 0 || y % 4 == 0 && y % 100 != 0) // p3 …; } … }
18
Build reachability predicates for the 6 predicates Identify test cases that satisfy PC, CC, CoC (complete the table) Are there infeasible requirements?
public static int daysInMonth(int m, int y) { if (m <= 0 || m > 12) // p1, c1, c2 throw new IllegalArgumentException("Invalid month: " + m); if (m == 2) { // p2, c3 if (y % 400 == 0 || y % 4 == 0 && y % 100 != 0) //p3, c4-6 return 29; else return 28; } if (m <= 7) { // p4, c7 if (m % 2 == 1) // p5, c8 return 31; return 30; } if (m % 2 == 0) // p6, c9 return 31; return 30; }
# m y expected reach & cover 1 -45 2016 IAE p1,c1 2 27 2016 IAE p1,c2 3 2 2016 29 ¬p1,¬c1,¬c2,p2, c3,p3,c5
Contracts: informal (e.g., Javadoc) or formal (e.g., JML) FSM abstractions
19
20
public Time(int h, int m) { … } public int getHours() { … } public int getMinutes() { … } /*@ @ public normal_behavior @ requires getMinutes() < 59; @ ensures getMinutes() == \old(getMinutes()) + 1; @ ensures getHours() == \old(getHours()); @ also @ public normal_behavior @ requires getMinutes() == 59 && getHours() < 23; @ ensures getMinutes() == 0 @ ensures getHours() == \old(getHours()) + 1; @ also @ public normal_behavior @ requires getMinutes() == 59 && getHours() == 23; @ ensures getMinutes() == 0; @ ensures getHours() == 0; @*/ public void tick() { … }
JML pre-conditions define the predicates
Exercise 4: Three test cases satisfy PC (and CC too). Identify them.
We need to cover predicate (and clause) isFull() See complete specification online: BoundedQueue and BoundedArrayQueue.
21
/*@ public normal_behavior requires !isFull(); ensures size() == \old(size()) + 1; ensures elementAt(\old(size())) == data; ensures (\forall int i; i >= 0 && i < \old(size()) ==> elementAt(i) == \old(elementAt(i))); also public exceptional_behavior requires isFull(); signals_only IllegalStateException; */ void enqueue(E data) throws IllegalStateException;
PC and CC do not subsume each other; CoC may easily become unpractical or lead to too many infeasible requirements. When we introduce tests at the clause level, we want also to have an effect on the predicate. Determination, the conditions under which a clause influences the outcome of a predicate. Idea: if you flip the clause, and the predicate changes value, then the clause determines the predicate. For p = a ⋀ ( b ∨ c ) the determination predicates are:
d(a) = b ∨ c — a determines p when b ∨ c d(b) = a ⋀ ¬ c — b determines p when a ⋀ ¬ c d(c) = a ⋀ ¬ b — c determines p when a ⋀ ¬ b
22
Let p ∈ P and c ∈ Cp. We say that c determines p if there is a logical assignment (determination predicate) d(c) to all other clauses s.t. changing the value of c changes the value of p.
The major clause is the clause on which we are focusing; all
clause. Finding the determination predicate d(c) = p[true/c] ⨁ p[false/c] where p[B/c] stands for p with every
23
Example 1 - taking p = a ∧ (b ⋁ c) d(a) = p[true/a] ⨁ p[false/a] = (b ⋁ c) ⨁ false = b ⋁ c d(b) = p[true/b] ⨁ p[false/b] = a ⨁ (a∧c) = a ∧¬c d(c) = p[true/c] ⨁ p[false/c] = a ⨁ (a∧b) = a ∧¬b Example 2 - taking p = a ⋁ (b ∧ c) d(a) = p[true/a] ⨁ p[false/a] = true ⨁ (b ∧ c) = ¬ (b ∧ c) = ¬b ⋁ ¬ c d(b) = p[true/b] ⨁ p[false/b] = (a ⋁ c ) ⨁ a = ¬a ∧c d(c) = p[true/c] ⨁ p[false/c] = (a ⋁ b ) ⨁ a = ¬a ∧b
24
d(c) = p[true/c] ⨁ p[false/c]
For p ∈ P and c ∈ Cp include two requirements in TR:
Example: 2 predicates involving 5 clauses yields 10 test requirements P = {p1, p2} , p1 = a ⋀ ( b ∨ c ) , p2 = x ∨ y d(a) = b ∨ c, d(b) = a ⋀ ¬c, d(c) = a ⋀ ¬b d(x) = ¬y, d(y) = ¬x TR(GACC) = {a ⋀ d(a), ¬a ⋀ d(a), b ⋀ d(b), ¬b ⋀ d(b), c ⋀ d(c), ¬c ⋀ d(c), x ⋀ d(x), ¬x ⋀ d(x), y ⋀ d(y), ¬y ⋀ d(y)}
25
Does GACC subsume PC ? Not necessarily. By definition GACC subsumes CC, but not PC (though this may happen in many practical cases of interest) Example: for p = a ↔ b we have d(a) = true and d(b) = true So TR(GACC) = {a, ¬a, b, ¬b} [Obs.: equivalent to TR(CC)] T1 = {[a=true, b=true], [a=false, b=false]} satisfies GACC but not PC. Both assignments to a and b yield p = true. T2 = {[a=true, b=false], [a=false, b=true]} would also satisfy GACC but not PC. Both assignments to a and b yield p = false. Does GACC subsume PC ? Not necessarily.
26
Idea: Correlate c∧d(c) with the truth value of the predicate. Note that c and p do not have to have the same value. For p ∈ P and c ∈ Cp include two requirements in TR:
that is, p must evaluate to true in one case and false in the other.
Example: given p = a ↔ b, we may have for clause a test set {TT, FT}, and for clause b test set {TT, TF}. Merging the two we obtain test set {TT, TF, FT} that satisfies CACC. By definition CACC subsumes GACC [thus CC] but also PC.
27
28
# a b c p = a ∧ (b ↔ c) Satisfies 1 T T T T a⋀d(a) b⋀d(b) c⋀d(c) 2 T T F F b⋀d(b) ¬c⋀d(c) 3 T F T F ¬b⋀d(b) c⋀d(c) 4 T F F T a⋀d(a) ¬b⋀d(b) ¬c⋀d(c) 5 F T T F ¬a ⋀ d(a) 6 F T F F − 7 F F T F − 8 F F F F ¬a⋀d(a)
Determination d(a) = b ↔ c d(b) = a d(c) = a
29
# a b c b ↔ c p = a ∧ (b ↔ c) Satisfies 1 T T T T T a ⋀ d(a) b ⋀ d(b) c ⋀ d(c) 2 T T F F F b ⋀ d(b) ¬c ⋀ d(c) 3 T F T F F ¬b ⋀ d(b) c ⋀ d(c) 4 T F F F T a ⋀ d(a) ¬b ⋀ d(b) ¬c ⋀ d(c) 5 F T T T F ¬a ⋀ d(a) 6 F T F F F − 7 F F T F F − 8 F F F F F ¬a ⋀ d(a)
As for CACC, but For p ∈ P and c ∈ Cp include two requirements in TR:
that is, p must evaluate to true in one case and false in the other (as in CACC) but additionally: the minor clause assignments must be the same in both cases.
Obs.: RACC subsumes CACC by definition. RACC imposes more “uniform” tests, but is also more likely to imply infeasible requirements.
30
CACC coverage for a: 9 possible choices: #1, #2, or #3 combined with one of #5, #6, or #7. RACC coverage for a: only 3 possible choices: #1 combined with #5, test #2 with #6, and #3 with #7.
31
# a b c p = a ∧ (b ⋁ c) Satisfies 1 T T T T a ⋀ d(a) 2 T T F T a ⋀ d(a) 3 T F T T a ⋀ d(a) 4 T F F F
−
5 F T T F
¬a ⋀ d(a)
6 F T F F
¬a ⋀ d(a)
7 F F T F
¬a ⋀ d(a)
8 F F F F
− d(a) = b ⋁ c
32
public static boolean isLeapYear(int y) { return y % 400 == 0 || y % 4 == 0 && y % 100 != 0; } a: y % 400 == 0 b: y % 4 == 0 c: y % 100 != 0 p: a ∨ (b ∧ c) d(a) = ¬b ∨ ¬c d(b) = ¬a ∧ c d(c) = ¬a ∧ b
TR(GACC)={(1) a ∧ (¬b ∨ ¬c), (2) ¬a ∧ (¬b ∨ ¬c), (3) b ∧ ¬a ∧ c, (4) ¬b ∧ ¬a ∧ c, (3) c ∧ ¬a ∧ b, (5) ¬c ∧ ¬a ∧ b}
# y expected clause values covered GACC requirements 1 2000 true
a b ¬c (1) a ∧ (¬b ∨ ¬c)
2 2001 false
¬a ¬b c (2) ¬a ∧ (¬b ∨ ¬c) (4) ¬b ∧ ¬a ∧ c
3 1900 false
¬a b ¬c (2) ¬a ∧ (¬b ∨ ¬c) (5) ¬c ∧ ¬a ∧ b
4 2004 true
¬a b c (3) b ∧ ¬a ∧ c
GACC coverage implies CACC coverage in this case RACC is also satisfied: (#1,#4) pair for a; (#2,#4) for b; (#3,#4) for c {#1, #2} satisfies CC and PC {#1, #3} satisfies PC but not CC CoC would lead to the following infeasible requirements a ∧ b ∧ c, a ∧ ¬b ∧¬c, a ∧ ¬b ∧ c, ¬a ∧ ¬b ∧¬c
33
public static boolean isLeapYear(int y) { return y % 400 == 0 || y % 4 == 0 && y % 100 != 0; } # y expected clause values covered GACC requirements 1 2000 true
a b ¬c (1) a ∧ (¬b ∨ ¬c)
2 2001 false
¬a ¬b c (2) ¬a ∧ (¬b ∨ ¬c) (4) ¬b ∧ ¬a ∧ c
3 1900 false
¬a b ¬c (2) ¬a ∧ (¬b ∨ ¬c) (5) ¬c ∧ ¬a ∧ b
4 2004 true
¬a b c (3) b ∧ ¬a ∧ c
34
public static TClass triangleType(int a, int b, int c) { if (a <= 0 || b <= 0 || c <= 0) // p1 return INVALID; if (a >= b + c || b >= a + c || c >= a + b) // p2 return INVALID; int count = 0; if (a == b) // p3 count++; if (a == c) // p4 count++; if (b == c) // p5 count++; if (count == 0) // p6 return SCALENE; if (count == 1) // p7 return ISOSCELES; return EQUILATERAL; }
Identify:
clauses of p1 and p2
requirements?