Figure 3: A graph representation of combined constraints.
e
ij
= (v
i
,v
j
) to E if v
i
and v
j
are subcondition of a path
condition in either V
P
or V
N
.
For example, in Figure 3 is the graph constructed
when we consider the program versions presented in
Figure 1 and the combined constraints in Table 1. In
the graph, there are three vertices corresponding to
three solvable constraints in Table 1. There is an
edge connecting v
1
and v
2
since their constraints are
both subconditions of P
1
. Similarly, v
2
and v
3
are
connected since their constraints are both
subconditions of Q
2
Next, we relate the test-case generation process in
the CTG
E
as graph traversal carried out in G. A
vertex v is considered visited if CTG
E
produces a
test-case satisfying the corresponding combined
constraint of v. According to Theorem 1, if all
vertices in G are visited after CTG
E
finishes, then
CTG
E
generates sufficient test-cases to detect any
regression bugs.
When CTG
E
begins, it starts by a certain test-case
I generated to satisfy a path condition α of V
P
. Using
symbolic execution, one can determine the path
condition β of V
N
which I belongs to. It means that a
vertex q = α∩β just has been initially visited.
Consider the formula α∩¬β referring to a vertex
q’, which should be connected to q since α∩β and
α∩¬β are both subcondition of α. Let C
mark
be the
formula representing all of vertices already visited
(i.e. the combined constraints whose corresponding
test-cases have been generated already). Similarly
reasoning, we finally obtain that the two formulas
α∩¬β∩¬C
mark
and ¬α∩β∩¬C
mark
should represent
all vertices connecting to q which have not been
visited. By recursively solving those formulas and
updating C
mark
in the subprocedure combine, CTG
E
will iteratively visit all of vertices in the connected
component which q belongs to.
Lastly, one can note that by checking all of path
conditions of V
P
, CTG
E
will travel to all possible
connected components of G. Thus, all vertices of G
will be logically visited when CTG
E
performed and
there are no vertices doubly visited.
For instance, consider using CTG
E
for generating
test-case for evolving programs in Listing 1. Firstly,
the two path conditions P
1
and P
2
are collected.
Then, CTG
E
generates randomly a test-case for a
path condition. Let it be n = 4 for P
1
. Performing
symbolic execution on the test-case, one can realize
that the test-case falls into the combined constraint
P
1
∧Q
1
= n>0 && n>3 = n >3. Then, CTG
E
tries to
solve the formula P
1
∧¬Q
1
∧¬C
mark
with C
mark
being
updated as C
mark
=P
1
∧Q
1
. We have P
1
∧¬Q
1
∧¬C
mark
= n>0 && ¬(n>3) && ¬(n>3) = n>0 && n≤3.
Then, a test-case is generated accordingly, e.g. n = 2.
Next, combine (2) is invoked, which is
corresponding to the constraint P
1
∧Q
2
with C
mark
being updated as n > 3 ∪ n>0 && n ≤3 = n> 0. We
then have P
1
∧¬Q
2
∧¬C
mark
= n>0 && n>3 &&
!(n>0) = ∅, then then this formula is not considered.
Meanwhile, we have ¬P
1
∧Q
2
∧¬C
mark
= !(n>0)
&& !(n>3) && !(n>0) = n≤0. Solving this
constraint, we, for instance, get a new test-case of n
= -7. Then, combine(-7) is invoked accordingly. At
the moment, C
mark
is updated as n > 0 ∪ !(n>0) &&
!(n>3) = n > 0 ∪ n ≤ 0, making P
2
∧¬Q
2
∧¬C
mark
=
¬P
2
∧Q
2
∧¬C
mark
=¬P
1
∧Q
1
∧¬C
mark
= ∅. Thus, the
algorithm stops with no more test-cases generated.
Complexity Analysis. Performing elementary
analysis on CTG
E
, one can realize that CTG
E
will
involve the embedded solver 2K times, with K is the
number of test-cases generated and K ≤ N+M where
N and M are the path conditions on V
P
and V
E
respectively. If we take into account the actions of
generating N path conditions on V
P
, the total
complexity of CTG
E
will be Ο(2K +M) ~ Ο(3N +M)
which should be improved significantly compared to
that of the original CTG.
To illustrate this, consider the two versions of
evolving programs given in Listing 3. The program
intends to grade students’ works. After the
preliminary version is finished as presented in
Listing 3(a), a new version is released afterward as
presented in Listing 3(b).
int grade(int n){
if(n > 100) return Invalid;
else if(n>=90) return Excellent;
else if(n>=80) return Very good;
else if(n>=70) return Good;
else if(n>=60) return Fairly good;
else if(n>=50) return Average;
else if(n>=0) return Fail;
else return Invalid;
}
(a) Student grading program – preliminary version
int grade(int n){
if(n > 100) return Invalid;
else if(n>90) return Excellent;
else if(n>80) return Very good;
else if(n>70) return Good;
else if(n>60) return Fairly good;
else if(n>50) return Average;
else if(n>0) return Fail;
else return Invalid;
}
(b) Student grading program – final version
Listing 3: Evolving programs.
ICSOFT 2011 - 6th International Conference on Software and Data Technologies
40