Tests et Validation du logiciel 02/2007 – 06/2007
Expression et nombre de chemins Rappel : Nb de chemins de contrôles = Nb de chemins exécutables + Nb de chemins non exécutables Certaines instructions comme le « for » génèrent énormément de chemins non exécutables
Expression et nombre de chemins For i:=1 to 1000 do s:=s+a[i]; Expression des chemins ? Nombre de chemins de contrôle ? Nombre de chemins exécutables et non exécutables ?
Hiérarchie des tests techniques Soit T1 un test structurel qui nécessite la couverture des chemins Soient δ1=cdebcde et δ2=ce T1= {δ1, δ2}. Soit DT1={a[1]=-2, a[2]=3, a[3]=17,i=1} une donnée de test qui sensibilise le chemin de contrôle M1= abcebcdebcdebf M1 couvre δ1=cdebcde et δ2=ce Donc DT1 satisfait T1
Hiérarchie des tests techniques Rappel : M1= abcebcdebcdebf Soient T1 = {cdebcde , ce} Soit un T2 nécessitant les couvertures des chemins suivantes T2={bcd, e} On remarque que si T1 satisfait, alors T2 l’est aussi On écrit : T1 T2 T1 est un test plus fort et plus fiable que T2 Règle de transitivité T1T2 et T2 T3 alors T1 T3
Catégories de critères de couverture Approche ‘Flot de contrôle’avec couverture de tous les arcs : DT1={x=-2, y=0} sensibilise le chemin M1=abcd DT2={x=1, y=0} sensibilise le chemin M1=ace Si l’affectation du noeud b est erronée, cette erreur ne sera pas détectée par DT1 et DT2. Approche ‘Flot de données’ L’affectation de y au noeud b n’est pas utilisée par DT1 et DT2 : il faudrait tester le chemin sensibilisé par la DT3={x=2, y=0}
Couverture de flot de contrôle Couverture de tous-les-noeuds But : sensibiliser tous les chemins de contrôle qui nous permettent de visiter tous les noeuds du graphe. Nom du critère de couverture : «tous les noeuds» A chaque critère de couverture est associée une valeur que l’on appelle taux de couverture ou mesure de complétude. Taux de couverture : TER1 (Test Effectiveness Ratio 1 ou C1) TER1 = {noeuds couverts} / {noeuds} TER1=1 C1=1 Tous-les-nœuds est satisfait Toutes les instructions ont été exécutées au moins une fois
Couverture de flot de contrôle Exemple Function sum (x,y: integer) : integer; Begin If (x=0) then sum := x Else sum := x + y; End; Un test fonctionnel ne permettrait pas de trouver le défaut. L’anomalie est détectée par le chemin [acd] Toutes les DTs fournissent un TER=0.75
Couverture de flot de contrôle Soit le programme Read(x); … If x<>0 then x:=1; Y:=1/x; Le critère tous-les-nœuds est satisfait par le chemin [abcd] cependant le bug ne sera pas mis en évidence
Couverture de flot de contrôle Couverture tous-les-arcs Le critère tous-les-nœuds est insuffisant pour détecter une majorité d’erreurs de programmation. TER2 = {arcs couverts} / {arcs} Lorsque le critère tous-les-arcs est totalement réalisé, cela implique que le critère tous-les-nœuds est satisfait Équivaut à la couverture de toutes les valeurs de vérité pour chaque nœud de décision
Couverture de flot de contrôle Conditionnelles composées Exemple : if ((a < 2) and (b = a)) Then x := 2 -a Else x := a -2 Le jeu de test DT1 = {a=b=1}, DT2 = {a=b=3} satisfait le critère tous-les-arcs sans couvrir toutes les décisions possibles -ex. DT3 = {a=3, b=2}.
Couverture de flot de contrôle Le graphe de flot de contrôle doit décomposer les conditionnelles : 4 DTs pour couvrir le multi graphe DT1={a=b=1} DT1={a=1,b=0} DT1={a=3 ,b=2} DT1={a=b=3}
Couverture de flot de contrôle Le critère condition-décision multiple est satisfait si Le critère tous les arcs est satisfait Chaque sous-expression dans les conditions prend toutes les combinaisons de valeurs possibles Si A & B Then ………..Nécessite : A = B = vrai A = B = faux A = vrai, B = faux A = faux, B = vrai Problème de la combinatoire lors d’expression logique complexe
Couverture de flot de contrôle Problème de la sensibilité du traitement des conditionnelles par le compilateur => proposer un graphe alternatif qui pourrait correspondre à une optimisation du compilateur
Couverture de flot de contrôle Note : bOK:=(a < 2) and (b = a); If bOK Then x := 2 -a Else x := a -2 Le problème devient « masqué » Ambiguïté du critère tous-les-arcs, car dépend de l’algo ainsi que du compilateur
Couverture de flot de contrôle Limites du critère tous-les-arcs et condition multiples Soit le programme suivant : évaluer l’inverse de la somme des éléments compris entre la place inf et sup d’un tableau a comprenant des entiers positifs read(inf, sup); i := inf; sum:= 0; while(i <= sup) do begin sum:= sum+ a[i]; i := i + 1; end; writeln(1/sum); Existe-t-il un bug potentiel ?
Couverture de flot de contrôle La DT1 = {a[1]=50, a[2]=60,a[3]=80, inf=1, sup=3} couvre le critère tous-les-arcs adbc B1={u1,u2, u3,u2, u3, u2, u3, u4} Problème non détecté par le critère tous-les-arcs: si inf >sup erreur sur 1/sum Chemin maquant : [u1,u4] avec DT2={inf=2,sup=1} B2={u1, u4}
Couverture du flot de contrôle Couverture de tous-les-chemins-indépendants Le critère tous-les-chemins-indépendants vise à parcourir tous les arcs dans chaque configuration possible (et non pas au moins une fois comme dans le critère tous-les-arcs) Lorsque le critère tous-les-chemins-indépendants est satisfait, cela implique : le critère tous-les-arcs est satisfait, le critère tous-les-nœuds est satisfait.
Couverture de flot de contrôle Sur le programme P7, l’arc [d-c] est sensibilisé lorsque i > sup dans le contexte sum= 0 (la boucle n’est pas activée) Dans le contexte sum≠0 (la boucle est activée)
Couverture du flot de contrôle Procédure : tous-les-chemins-indépendants 1 –Evaluer V(G) -> nombre cyclomatique NB : e – n + i + s OU Nb conditions simples +1 2 -Produire une DT au hasard couvrant le maximum de noeuds de décisions du graphe 3 -Produire la DT qui modifie la valeur de vérité (donc le flot) de la première instruction de décision de la DT de la seconde étape Recommencer l’étape 3 jusqu’a la couverture de toutes les décisions.
Couverture du flot de contrôle Exemple : soit le programme suivant Function goodstring(var count : integer) : boolean; var ch : char; begin goodstring:= false; count := 0; read(ch); if ch = ‘a’ then read(ch) while(ch=‘b’) or (ch=‘c’) do count := count + 1; end; if ch = ‘x’ then goodstring= true; La fonction goodstring est censée reconnaître toutes les chaînes de caractères (fournies caractère par caractère) commençant par le caractère a, suivi d’une série de b ou c (dont le nombre sera compté ) et se terminant par x. Si la chaîne est reconnue alors la fonction retourne vrai, sinon elle retourne false.
Couverture du flot de contrôle Construisez le graphe de flot de contrôle en décomposant les conditions multiples. Appliquez la démarche
Couverture du flot de contrôle
Couverture du flot de contrôle 1) V(G) = 13-11+2 = 4+1 = 5 5 Chemins indépendants à trouver 2) DT normale = « abcx » Chemin sensibilisé : B1={0,1,2,3,4,5,3,6,4,5,3,6,7,8,9} 3) On choisi la première décision de B1 (1). La première était vrai, on choisi une DT pour l’inverser et donc sensibiliser le chemin B2 {0,1,9}. Dt=« b » B1 et B2 sont indépendants 3) On choisi la seconde décision de B1 (3) Première itération. Valeur vrai : arc(3,4) Dt dont le seconde caractère est <> de b. Ex DT3={(acx} Chemin sensibilisé : B3 {0,1,2,3,6,4,5,3,6,7,8,9} B1 contient {3,4} qui n’est pas dans B3 et B2 contient {1,9} qui n’est pas dans B3. B1, B2, B3 sont indépendants 2 à 2 3) Troisième condition….
Couverture du flot de contrôle Cette technique a mis en évidence 5 DT DT1={abcx} DT2={b} DT3={acx} DT4={ax} DT5={aba} Ces DT mettent en évidence les chemins de base du graphe précédent. Nb : les DT 1, 2 et 5 suffisent à satisfaire tous-les-arcs.
Couverture du flot de contrôle Pour prouver que des chemins sont indépendants, il suffit de trouver un arc qui n’est pas contenu dans les deux chemins Si il n’y a plus de conditions à étudier sur le chemin initial, on peut enchaîner sur les chemins secondaires mis en évidence
Couverture de flot de contrôle Exercice: Soit le programme P3 suivant : If n ≤0 then n := 1-n end; If n pair Then n := n / 2 Else n := 3*n + 1 end ; Write(n); Graphe de flot Calculer les DT suivant les critères : tous-les-noeuds, tous-les-arcs, tous-les-chemins-indépendants
Couverture du flot de contrôle Critères de test : tous-les-noeuds n = 0, n = -1 tous-les-arcs n = 2, n = -2 tous-les-chemins-indépendants n = -1, n = -2, n = 1, n = 2