8.5 Filtrage
8.5.1 Filtrage `a la g´en´eration
Cr´eation des contraintes
Nous avons d´efini chapitre 6 un m´ecanisme de filtrage `a la g´en´eration. Ce syst`eme
per-met d’exprimer des contraintes sous la forme d’op´erations VDM retournant un bool´een. Ces
op´erations renvoient la valeur vrai lorsque la contrainte est satisfaite et faux dans le cas
contraire. Pour chaque test g´en´er´e, nous v´erifions si la contrainte est satisfaite. Si tel est le
cas, le test est conserv´e sinon il est supprim´e.
Le sch´ema TestSeqEvent g´en`ere1372 s´equencesde test. Parmi toutes ces s´equences, un
certain nombre nous semblent inutiles comme par exemple :
seq 1 = load_table({"e1"|->1, "e2"|->1, "e3"|->1}); add_student("e1");
add_student("e1"); add_student("e1")
seq 2 = load_table({"e1"|->1, "e2"|->1, "e3"|->1});
swap_two_student("e1","e10") ...
La premi`ere de ces deux s´equences ne nous int´eresse pas car ajouter trois fois le mˆeme
´etudiant est, selon nous, ´equivalent `a l’ajout d’un ´etudiant d´ej`a pr´esent dans la table.
Nous faisons donc l’hypoth`ese de r´egularit´e suivante : ajouter un ´etudiant d´ej`a pr´esent
est ´equivalent au fait d’ajouter plusieurs fois le mˆeme ´etudiant.
La deuxi`eme s´equence va n´ecessairement conduire `a un verdict inconclusif puisqu’elle
viole la pr´econdition de l’op´eration TestSwapTwoStudents.
Nous avons d´efini une op´eration VDM renvoyant un bool´een qui nous permet d’´eliminer
une grande partie de ces tests. Pour ce faire, nous cr´eons des variables et les lions aux
param`etres des op´erations entrant en jeu dans ces tests. Ainsi, :
– tableIn est la variable reli´ee au param`etre de load table,
– studentAdd est la variable reli´ee au param`etre d’add student,
– studentDepetstudentArrsont les variables li´ees respectivement au premier et second
param`etre de l’op´eration swap two students.
Ces variables repr´esentent des s´equences d’´el´ements. Ainsi tableIn est une s´equence de
tables. Par exemple, si nous reprenons les deux s´equences pr´esent´ees ci-dessus, nous aurons :
1. pour seq 1 :
– tableIn = [{"e1"|->1, "e2"|->1, "e3"|->1}]
– studentAdd = ["e1", "e1", "e1"]
– studentDep = []
– studentArr = []
2. pour seq 2 :
– tableIn = [{"e1"|->1, "e2"|->1, "e3"|->1}]
– studentAdd = []
– studentDep = ["e1"]
– studentArr = ["e10"]
L’op´eration est la suivante :
contrainte1: () ==> bool
contrainte1 == (
dcl setIn : set of student:={};
for all t in set elems(tableIn) do
(setIn := setIn union dom t;);
return (
card(elems(studentAdd)) = len(studentAdd) and
elems(studentArr^studentDep) subset (setIn union elems(studentAdd))
))
La variable setIn permet de r´ecup´erer tous les ´etudiants pr´esents dans les diff´erents
groupes sous la forme d’un ensemble afin de pouvoir exprimer nos contraintes.
– card(elems(studentAdd)) = len(studentAdd) garantit que les ´etudiants ajout´es
sont tous diff´erents : elems prend une s´equence d’´el´ements en entr´ee et renvoie
l’en-semble contenant tous les ´el´ements contenus dans la s´equence (si un ´el´ement est pr´esent
plusieurs fois dans la s´equence, il ne sera pr´esent qu’une seule fois dans l’ensemble) ;
len renvoie la longueur de la s´equence. Cela nous permet d’´eliminer les cas o`u l’on
essaie d’ajouter deux fois le mˆeme ´etudiant. Les tests correspondant `a seq 1sont ainsi
supprim´es.
– elems(studentArr^studentDep) subset (setIn union elems(studentAdd))
per-met de supprimer des cas inconclusifs puisqu’il s’agit d’enlever toutes les tentatives
de permutation lorsque l’un des deux ´etudiants n’est jamais pr´esent dans la table au
cours du test. En effet, nous concat´enons les s´equences studentArr et studentDep,
construisons l’ensemble des ´etudiants qui sont pr´esents dans la table au cours du test
(setIn union elems(studentAdd)) et nous v´erifions que l’ensemble des ´etudiants
que l’on va permuter
elems(studentArr^studentDep)est bien un sous-ensemble de l’ensemble des ´etudiants
pr´esents dans la table.
Comme nous ne prenons pas en compte l’ordre des appels dans la contrainte, les s´equences
de test de la forme
seq 3 = load table({"e1"|->1, "e2"|->1, "e3"|->1});
swap two students("e1","e10"); add student("e10") ...
ne sont pas rejet´ees alors que la sp´ecification de swap two students est viol´ee.
Nous avons montr´e au chapitre 6 que de telles s´equences pouvaient ˆetre prises en compte
en extrayant une information plus d´etaill´ee, mais cela se fait au d´etriment de l’expression de
la contrainte. Pour ce faire, les variables que nous avons utilis´ees doivent ˆetre d´efinies sous
la forme de fonctions ayant pour domaine l’indice d’appel et pour codomaine la valeur de
l’appel, et non plus sous la forme de s´equences. Nous aurons alors :
1. pour seq 1 :
– tableIn = {1|->{"e1"|->1, "e2"|->1, "e3"|->1}}
– studentAdd = {2|->"e1", 3|->"e1", 4|->"e1"}
– studentDep = {}
– studentArr = {}
2. pour seq 2 :
– tableIn = {1|->{"e1"|->1, "e2"|->1, "e3"|->1}}
– studentAdd = {}
– studentDep = {2|->"e1"}
– studentArr = {2|->"e10"}
3. pour seq 3 :
– tableIn = {1|->{"e1"|->1, "e2"|->1, "e3"|->1}}
– studentAdd = {3|->"e10"}
– studentDep = {2|->"e1"}
– studentArr = {2|->"e10"}
Si nous ´ecrivons la contrainte :
1 contrainte2: () ==> bool
2 contrainte2 == (
3 return (
4 (forall i in set dom studentArr &
5 exists j in set 1,...,i-1 &
6 (j in set dom studentAdd
7 and studentAdd(j) = studentArr(i)
8 ) or (
9 j in set dom tableIn
11 )
12 ) and (
13 forall i in set dom studentDep &
14 exists j in set 1,...,i-1 &
15 (j in set dom studentAdd
16 and studentAdd(j) = studentDep(i)
17 ) or (
18 j in set dom tableIn
19 and studentDep(i) in set dom tableIn(j)
20 )
21 )
22 )
Nous voyons que contrainte2 est beaucoup plus complexe que contrainte1. Pour
chaque ´etudiant d’arriv´ee de l’op´eration swap two students (ligne 4), nous v´erifions qu’il
existe un indice ant´erieur (ligne 5) tel que, l’´etudiant d’indice i dans studentArr ait ´et´e
pr´ec´edemment ajout´e (lignes 6 et 7) par l’op´erationadd student ou qu’il ait ´et´e charg´e dans
une table (lignes 7 et 8) par l’op´eration load table. Les lignes 13 `a 19 font la mˆeme chose
avec l’´etudiant de d´epart de l’op´eration swap two students.
Ex´ecution des contraintes
Nous avons g´en´er´e les tests `a partir du sch´ema TestSeqEvent. Le temps d’´evaluation
de la contrainte VDM d´efinie sur ce sch´ema est de 1 minutes et 11 secondes, elle permet
d’´eliminer574 s´equencesde tests ce qui nous donne une nouvelle suite de tests appel´ee suite
3.
Lorsque l’on ´etudie les erreurs lev´ees par cette suite de tests (voir table 8.2), nous pouvons
constater que ce sont les mˆemes que celles lev´ees par la suite initiale. Le filtrage n’a donc
pas diminu´e la qualit´e de la suite de tests nous confortant ainsi dans l’id´ee que nous avons
fait de bonnes hypoth`eses de test.
Dans le document
Outils pour la synthèse de tests et la maîtrise de l'explosion combinatoire.
(Page 146-149)