• Aucun résultat trouvé

Problématique et motivations

5.4 Génération de modèles

5.4.1 Problématique et motivations

Afin d’illustrer les discussions de cette section, nous utilisons, une fois de plus

l’exemple présenté dans la section 5.2.1. La transformation à tester est la mise-à-plat

de machines à états conformes au méta-modèle rappelé par la figure 5.26. L’utilisation

du partitionnement a permis d’associer des partitions à chaque propriété de ce

méta-modèle (la figure 5.4). Grâce au framework et aux critères proposés dans les sections 5.2

et 5.3 les classes d’équivalences de ces partitions sont combinées pour former des

frag-Génération de modèles 171

ments d’objets et de modèles. La figure 5.25 présente trois ensembles de cinq fragments

de modèles. Les deux premiers ensembles de fragments de modèles ont été obtenu en

construisant aléatoirement cinq fragments de modèles très simples (contenant chacun

un seul fragment d’objet). Le troisième ensemble correspond à cinq fragments de

mo-dèles produits par le critèreIF ClassQ. L’objectif de la phase de génération de modèles

est de produire des modèles qui permettent de couvrir des ensembles de fragments de

modèles comme ceux-ci.

M F{AbstractState(label= 0)},M F{Composite(]ownedState= 0)},

M F{T ransition(]source= 1)},M F{T ransition(event.+)},

M F{AbstractState(]outT rans.= 1)}

M F{Composite(]ownedState2)},M F{AbstractState(label= 1)},

M F{AbstractState(]inT rans.2)},M F{T ransition(event=

00

)},

M F{State(isF inal=true)}

M F{AbstractState(label= 1, ]inT rans.= 1, ]outT rans.= 0),

State(isF inal=true, isInitial=f alse)},

M F{T ransition(event.+, ]source= 1, ]target= 1)},

M F{AbstractState(label= 1, ]inT rans.2, ]outT rans.= 1),

State(isF inal=f alse, isInitial=true)},

M F{T ransition(event=

0

ev1

0

, ]source= 1, ]target= 1)},

M F{AbstractState(label2, ]inT rans.2, ]outT rans.= 0),

Composite(]ownedState= 1)},

Fig. 5.25 –Trois ensembles de cinq fragments de modèles.

Le premier ensemble de fragments de modèles de la figure 5.25 spécifie que

l’en-semble des modèles de test doit contenir :

– Un état dont l’étiquette est0.

– Un état composite vide.

– Une transition ayant un état source.

– Une transition portant un évènement quelconque.

– Un état ayant une transition sortante.

A partir de cet ensemble de fragments, il est possible de vérifier si un ensemble de

modèles est satisfaisant. Il suffit pour cela de rechercher au moins un modèle contenant

chaque fragment de modèle. Cependant, le fait de générer des modèles dans le but de

couvrir ces fragments n’est pas direct dans la mesure où il n’existe pas de solution

unique. La figure 5.27 présente, par exemple, deux ensembles de modèles construits

manuellement dans le but de satisfaire ces cinq propriétés. Le premier ensemble compte

un seul modèle (A.1) qui concentre tous les éléments demandés. Le second ensemble

compte trois modèles : B.1 qui couvre la première propriété, B.2 qui couvre la seconde

et B.3 qui couvre les trois dernières.

La génération automatique de modèles de test, comme ceux de la figure 5.27, pose

deux problèmes : les modèles générés doivent être valides (conformes au méta-modèles

et aux contraintes qui lui sont associées) et les modèles générés doivent être minimaux

(en nombre et en taille).

Fig. 5.26 –Méta-modèle de machines à états composites.

Fig.5.27 –Exemple d’ensembles de modèles conformes au méta-modèle de la figure 5.26 permettant

de couvrir les cinq premiers fragments de modèles de la figure 5.25.

Génération de modèles 173

Validité des modèles générés

Le premier problème est que les modèles de test doivent être conformes à un

méta-modèle donné et aux éventuelles contraintes qui lui sont associées. Les fragments de

modèles ne peuvent pas être directement utilisés pour le test car il ne constituent pas

des modèles valides vis-à-vis du méta-modèle : il faut les compléter. Pour être conformes

à un méta-modèle il est nécessaire que tous les objets d’un modèle respectent les types

et les multiplicités des propriétés du méta-modèle. Si l’on considère le méta-modèle de

la figure 5.26 cela signifie par exemple que chaque transition d’un modèle doit avoir un

état source et un état cible. Pour créer un modèle valide contenant une transition, il

est donc nécessaire que ce modèle contienne au moins un état.

Pour être conforme à un méta-modèle, un modèle doit vérifier les contraintes

asso-ciées à ce méta-modèle. Ces contraintes sont généralement exprimées en OCL (d’autres

langages déclaratifs ou impératifs peuvent également être utilisés) et doivent être

véri-fiées par les modèles de test. Par exemple, dans le cas du méta-modèle d’automate, pour

qu’un automate soit valide il faut qu’il ait un seul état initial. Ce type de contrainte

doit être pris en compte lors de la génération automatique de modèles.

En pratique, il est possible d’assurer par construction que la structure d’un modèle

est en accord avec les structures décrites par un méta-modèle. Dans un environnement

de modélisation comme Kermeta, ce niveau de conformité est en grande partie garanti

par l’environnement. En effet, la gestion des associations et compositions et le typage

fort permettent de s’assurer que tout objet possède une méta-classe et que les types des

valeurs de ses propriétés sont correctes. La seule contrainte qui n’est pas assurée par

l’environnement est le respect des bornes inférieures des multiplicités des propriétés.

Les deux techniques que nous présentons dans la suite permettent d’assurer la tenue

de cette contrainte.

En ce qui concerne le respect des contraintes associées au méta-modèle, le problème

est plus difficile à résoudre. Ces contraintes étant quelconques, elles sont impossible à

assurer par construction dans le cas général. La solution que nous proposons est, dans

la première technique, un filtrage à posteriori des modèles de test et, un filtrage des

modèles au cours de la génération dans la seconde.

Taille et nombre de modèle générés

En plus des deux exemples de la figure 5.27, un grand nombre d’ensembles solutions

peut être construit. Ces ensembles diffèrent principalement par le nombre et la taille

des modèles qui les composent. En effet, pour couvrir un ensemble de fragments de

modèles, deux stratégies extrêmes peuvent être envisagées :

– La première est de créer un modèle de test par fragment de modèle à couvrir. Dans

ce cas l’ensemble de modèles obtenu comportera un grand nombre de modèles

(autant que de fragment de modèles) et ces modèles seront de petite taille.

– La seconde est de couvrir tous les fragments de modèles dans un unique modèle

de test. Dans ce cas, un seul modèle de test est généré mais ce modèle à une taille

importante. C’est cette stratégie qui a été utilisée pour créer le modèle A.1 de la

figure 5.27.

Pour le bon déroulement de la phase de test, il faut trouver un compromis entre

ces deux stratégies. D’une part, il faut minimiser le nombre de modèles de test afin

de réduire les coûts liés, entre autres, à la production de l’oracle. D’autre part, il faut

que les modèles de test soit aussi petits que possible pour faciliter la localisation des

erreurs détectées par un modèle de test (diagnostique). Les deux techniques que nous

proposons permettent d’ajuster ce compromis.