• Aucun résultat trouvé

Exemple 1.2 (Cas de test) La figure 1.3 présente un exemple de cas de test pour une machine à café obtenu à partir de la spécification montrée dans la

1.3.4 Principes de la génération de tests symboliques

1.3.4.2 Produit synchrone

.

1.3.4.1 Rendre complet un cas de test

Dans la théorie du test présentée dans ce document, les cas de test, jouant le rôle de mécanisme de sélection, doivent être complets par rapport à leur spécification. En pratique, cette exigence complique souvent le processus d’écriture des objectifs de test. Ainsi, nous décidons d’accepter des objectifs de test incomplets de la part du programmeur et de les compléter automatiquement à la première étape du processus de génération de tests. Ceci nous permet de nous focaliser sur les comportements souhaités du système sous test en simplifiant sensiblement le processus d’écriture de l’objectif de test.

Néanmoins, il est facile d’assurer syntaxiquement la complétion de l’objectif de test par rapport à sa spécification. En effet, s’il existe une transition symbolique

sortant d’une localité, étiquetée par une action % et qui ne mène pas à la localité

  

 , alors, nous ajoutons une transition symbolique de à   

 , gardée par

la négation de la disjonction de toutes les gardes des transitions étiquetées par

l’action % et sortant de . Sinon, nous ajoutons une boucle sur étiquetée % . Le

lecteur peut trouver l’algorithme qui rend complet un objectif de test donné par rapport à sa spécification à la section 7.1 du chapitre 7. Enfin, la figure 1.5(b) illustre un objectif de test complet obtenu à partir de la spécification montrée à la figure 1.1 et l’objectif de test dépeint à la figure 1.5(a) par l’algorithme expliqué intuitivement plus haut.

1.3.4.2 Produit synchrone

Pour l’étape suivante de notre méthode de génération de tests, nous calculons

un produit synchrone

 entre une spécification 

et un objectif de test 

complet relativement à 

(voir section précédente). Le but de cette phase est

d’identifier les comportements de 

comme acceptés par  . L’idée d’utiliser

l’opération produit afin de marquer les comportements de 

a déjà été em-ployée en génération de tests, voir par exemple les articles suivants [Jéron and Morel, 1999], [Jard and Jéron, 2002]. Nous construisons le produit synchrone

 à partir des 

et  donnés en utilisant l’opération produit définie au

paragraphe Produit page ix.

8

xxii Résumé

(pBev = COFFEE)

Deliver ! (pBev) Cancel ?

(vPaid < cPrice) Return ! (pRemVal)

Start

Begin

Accept Reject

(a) Objectif de test  .

Begin tau Coin ? ChooseBeverage ? not (vPaid < cPrice) Return ! (pRemVal)

Accept

(pBev = COFFEE) Deliver ! (pBev)

Reject

Cancel ? (vPaid < cPrice) Return ! (pRemVal)

not (pBev = COFFEE) Deliver ! (pBev)

* *

(b) Objectif de test complet .

Figure 1.5: Rendre complet un objectif de test donné  par rapport à sa

spé-cification  montrée à la figure 1.1 (voir page iv).

Il est important de souligner que comme   et  sont compatibles pour

l’opération produit, et que  est complet par rapport à   , alors, à cause du

second point de la Proposition 1.1 (voir page x), nous obtenons que l’opération

produit conserve l’ensemble des traces de   , c’est-à-dire :      

      !#" $ %'&

.

Il est aussi important de signaler que les comportements acceptés du produit

synchrone   () sont, à une projection près, les comportements de  

acceptés par  . Par contre, nous avons obtenu seulement l’inclusion des traces

acceptées de   *+ dans l’intersection des traces de   et des traces

accep-tées de  , c’est-à-dire : ,-     ./0-12     435,-  670 .

Cette inclusion provient de la projection (voir la proposition 1.2 page xiv). Exemple 1.3 (Produit synchrone) La figure 1.6 (voir page xxiii) montre le résultat du calcul du produit pour la spécification d’une machine à café (voir figure 1.1, page iv) et pour l’objectif de test de cette spécification décrit à la figure 1.5(b) (voir page xxii). Le but de cet exemple est de souligner le fait que l’opération produit marque des localités de la spécification donnée avec

,8   #:9 , rendant les comportements qui y mènent acceptés par l’objectif de test. Les comportements acceptés du produit calculé apparaîssent en vert sur

Génération de tests sym b oliques xxiii

(cPrice > 0) and (vPaid = 0) and (vBeverage = TEA)

<Begin,Begin> <Idle,Begin> tau vPaid := 0 <Pay,Begin> (pCoinValue > 0) Coin ? (pCoinValue) vPaid := (vPaid + pCoinValue)

<Return,Reject>

Cancel ? ((pRemaningValue = cPrice - vPaid) and (vPaid < cPrice) and not(vPaid < cPrice))

Return ! (pRemaningValue)

<Idle,Reject>

((pRemaningValue = cPrice - vPaid) and (vPaid < cPrice)) Return ! (pRemaningValue)

<Choose,Reject> ((pRemaningValue = vPaid - cPrice) and

(vPaid >= cPrice) and (vPaid < cPrice)) Return ! (pRemaningValue)

vPaid := cPrice

<Choose,Begin> ((pRemaningValue = vPaid - cPrice) and

(vPaid >= cPrice) and not(vPaid < cPrice)) Return ! (pRemaningValue) vPaid := cPrice <Begin,Reject> (pRemaningValue = vPaid) Return ! (pRemaningValue) Cancel ? <Pay,Reject> (pCoinValue > 0) Coin ? (pCoinValue) vPaid := (vPaid + pCoinValue)

Cancel ? <Delivery,Reject> ChooseBeverage ? (pBeverage) vBeverage := pBeverage Cancel ? <Delivery,Begin> ChooseBeverage ? (pBeverage) vBeverage := pBeverage tau vPaid := 0

((vPaid < cPrice) and (pRemaningValue = cPrice - vPaid))

Return ! (pRemaningValue)

((vPaid >= cPrice) and (pRemaningValue = vPaid - cPrice))

Return ! (pRemaningValue) vPaid := cPrice

(vBeverage = pBeverage) Deliver ! (pBeverage)

((vBeverage = pBeverage) and not(pBeverage = COFFEE)) Deliver ! (pBeverage)

<Begin,Accept> ((vBeverage = pBeverage) and

(pBeverage = COFFEE)) Deliver ! (pBeverage) <Idle,Accept> tau vPaid := 0 <Pay,Accept> (pCoinValue > 0) Coin ? (pCoinValue) vPaid := (vPaid + pCoinValue)

<Return,Accept> Cancel ? ((vPaid < cPrice) and

(pRemaningValue = cPrice - vPaid)) Return ! (pRemaningValue)

<Choose,Accept>

((vPaid >= cPrice) and (pRemaningValue = vPaid - cPrice))

Return ! (pRemaningValue) vPaid := cPrice (pRemaningValue = vPaid) Return ! (pRemaningValue) Cancel ? <Delivery,Accept> ChooseBeverage ? (pBeverage) vBeverage := pBeverage (vBeverage = pBeverage) Deliver ! (pBeverage)

Figure 1.6: Produit synchrone 

      .

xxiv Résumé la figure 1.6 (voir page xxiii). Tous les autres comportements, imprimés en rouge, sont considérés comme rejetés. Les comportements rejetés indiquent les comportements de la spécification pour lesquels le cas de test ne sera pas généré. Ils seront éliminés au cours des étapes suivantes de la méthode de génération de tests.

Les prochains pas de la méthode de génération de tests décrite dans le reste de ce

chapitre consistent à transformer et à simplifier le produit       0 afin

d’obtenir un cas de test correct dans le sens de la définition 1.7 (voir page xix). 1.3.4.3 Construction de comportements visibles

Il est important d’insister sur le fait que le test n’autorise pas le non-déterminisme car les verdicts de test ne doivent pas dépendre des choix internes du testeur. C’est pourquoi cette étape de la méthode de génération de tests est réservée à

l’élimination des actions internes de l’IOSTS  , c’est-à-dire à la construction de



# 0, et à la résolution de choix non-déterministes restant pour les actions

d’entrée/sortie de







# - . Pour cela, nous proposons les opérations syntaxiques de clôture et de déterminisation telles que :

  # 0     # -     6      0 ' (1.1) ,-  # 0 ,-    # -   ,-        0 ' (1.2) Les procédures de clôture et de déterminisation et leurs propriétés sont décrites aux sections A.1 et A.2 du chapitre 7, et brièvement résumées dans les deux paragraphes suivants.

Clôture : éliminer les actions internes. Pour éliminer des actions internes

de  , l’idée est de calculer l’effet de toute séquence d’actions internes qui mène

à une transition symbolique étiquetée par une action d’entrée ou de sortie, et de coder cet effet dans la garde et les affectations de la dernière transition symbol-ique.

Ceci résulte en une procédure syntaxique simple qui termine si l’IOSTS 

n’a pas de blocages vivants syntaxiques (c’est-à-dire des cycles d’actions internes). Ceci est une hypothèse courante en test de conformité [Tretmans, 1999] posée pour

l’ensemble de ce travail de recherche. Soit 

   ! "   #$ une séquence de

transitions symboliques étiquetées par les actions internes %&'(% et menant

à la transition symbolique  #$

)



 *#+ étiquetée par l’action , d’entrée ou de sortie (voir figure 1.7(a), page xxv). Supposons que les gardes et les affectations

correspondant à %.- (/ 10&243 ) sont 56- et 78-; et que les gardes et les affectations

correspondant à , sont 5

) et 7

Génération de tests symboliques xxv                

(a) Un fragment d’un IOSTS  montrant une de ses séquences d’actions internes.

        !  #"$%&  '(  )  !  "$&  '  #  )  !  "*%&  

(b) Un fragment de l’IOSTS +#,-/. 021 324576 obtenu à partir de  par la procédure de clôture.

Figure 1.7: Un exemple de l’IOSTS 

# -.

transition symbolique d’origine  , de destination  #+ , d’action , , de garde 5 98

56;: 7 '<8 /8 56 =: 7 *> ?: 76@8 56 A: 78 =: 78 $> ?:   7 ' , et d’affectations

7

)

: 78 B: 7 *> C:6 76, où : est le symbole de la composition de fonctions (voir figure 1.7(b), page xxv).

Déterminisation. La déterminisation consiste à retarder l’effet d’un choix non-déterministe sur les actions observables qui le suivent. Par exemple, cela revient à transformer en trois transitions deux transitions symboliques (avec les gardes

non-exclusives 5  et 5  et les affectations 7  et78 voir figure 1.8(a), page xxvi).

Une transition pour le cas où 5 =8ED 56  est vrai, une autre pour le cas où

D 5 /8 5   est vrai, et la dernière pour le cas où  5 F8 5   est vrai. Dans ce dernier

cas, le choix d’affecter les variables selon 7  ou 78 est retardé jusqu’à l’action

observable qui suit. Ainsi, si G est la prochaine action, alors l’affectation 7  doit

avoir été exécutée, donc l’affectation est composée de la garde et de l’affectation

correspondant à G , ce qui produit la garde  5H;: 76 et les affectations 7IH;: 76 .

De la même manière, si J est la prochaine action, alors 7  doit être exécuté, ce

qui produit la garde 5LK<: 78  et les affectations 7MK?: 78 . Le résultat de l’IOSTS

obtenu par la procédure expliquée plus haut est montré à la figure 1.8(b) (voir page xxvi).

Il est important de remarquer que cette procédure peut ne pas terminer (par

exemple si G  , et NH  , le retard continue à l’infini). Cependant, elle termine

pour un IOSTS appartenant à la sous-classe non-triviale des IOSTS déterministes

xxvi Résumé                             

(a) Fragment d’un IOSTS   !#"%$'&, où les transitions() et (+* qui sont impliquées dans un choix non-déterministe, sont montrées en pointillé.

, ,- ,. ,/ ,0 ,- 1. 23 -5476 3 .+8 9 2 :; 8 < -2 6 3 -54 3 .#8 9 2 :; 8 < . 2=3 ->4 3 .+8 9 2:; 8 23 / ? < -@8 A 2 : /8 2< / ? < -B8 23 05? < .+8 C 2: 0 8 2< 0D? < .+8 3 / A 2 : /8 < / 3 0 C 2: 08 < 0

(b) Fragment de l’IOSTS EDFHGJILKMNOP Q F I#R%S'TUT obtenu à par-tir deKMN OJP5QVF5I+R%S'T par la procédure de déterminisation (les localités et transitions symboliques nouvelles ou modifiées sont montrées en pointillé).

Génération de tests symboliques xxvii

Exemple. La figure 1.9 page xxvii illustre l’IOSTS (- 

.



 # 0'

obtenu après extraction des comportements observables de l’IOSTS  montré à

la figure 1.6 page xxiii (c’est-à-dire après application des procédures de clôture et de déterminisation expliquées dans les deux derniers paragraphes). Les transitions en bleu sur cette figure indiquent deux nouvelles transitions symboliques qui

remplacent les deux séquences d’actions internes de l’IOSTS  .

Documents relatifs