Test du Logiciel
Exercice 1 - Partition en classes et valeurs frontières L'objectif de cet exercice est d'identifier les classes d'équivalence pour différentes spécifications, puis de proposer un jeu de test utilisant les valeurs frontières. Le document source présente les solutions dans le désordre ; elles ont été réorganisées ici pour correspondre à l'ordre des questions.
D'après le document Test du Logiciel
Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Document source
Génie Logiciel, Programmation · École Nationale des Sciences de l'Informatique (ENSI) · PDF · 5 pages · 2016
Afficher l'aperçu du document
Exercice 1 - Partition en classes et valeurs frontières
L'objectif de cet exercice est d'identifier les classes d'équivalence pour différentes spécifications, puis de proposer un jeu de test utilisant les valeurs frontières. Le document source présente les solutions dans le désordre ; elles ont été réorganisées ici pour correspondre à l'ordre des questions.
Question 1 - Maximum entre deux nombres
Spécification : Une méthode retourne le maximum entre deux nombres.
Pour deux nombres a et b, les relations possibles déterminent nos classes d'équivalence (D) :
- D1 : {(a, b) | a > b}
- D2 : {(a, b) | a < b}
- D3 : {(a, b) | a = b}
Jeu de test :
- Pour D1 : (5, 2)
- Pour D2 : (2, 5)
- Pour D3 : (5, 5)
Question 2 - Parité d'un nombre
Spécification : Une méthode retourne vrai si on entre un nombre pair et faux sinon.
Un nombre entier d est soit pair, soit impair. L'opérateur modulo (mod) permet de définir ces classes :
- D1 : {d | d mod 2 = 0} (nombres pairs)
- D2 : {d | d mod 2 = 1} (nombres impairs)
Jeu de test :
- Pour D1 : (2)
- Pour D2 : (3)
Question 3 - Calcul conditionnel selon la parité
Spécification : Une méthode retourne trois fois le nombre entré + 28 si le nombre est impair et la racine carrée sinon.
Bien que le traitement mathématique diffère de la question précédente, la condition d'embranchement repose exactement sur la même logique de parité. Les classes d'équivalence sont donc identiques :
- D1 : {d | d mod 2 = 0} (déclenchera la racine carrée)
- D2 : {d | d mod 2 = 1} (déclenchera le calcul 3d + 28)
Jeu de test :
- Pour D1 : (2)
- Pour D2 : (3)
Question 4 - Feux de circulation
Spécification : Un programme prend les couleurs des feux de circulation en entrée et retourne la consigne de sécurité.
Les entrées valides sont les trois couleurs standard. Il est également crucial de définir une classe pour les entrées invalides afin de tester la robustesse du programme :
- D1 : {rouge}
- D2 : {vert}
- D3 : {jaune}
- D4 : {d | d ≠ rouge et d ≠ vert et d ≠ jaune}
Jeu de test :
- (rouge), (vert), (jaune), (couleur) où "couleur" représente une chaîne de caractères quelconque invalide, comme "bleu".
Question 5 - Calcul des impôts
Spécification : Paliers d'imposition selon le revenu d.
Nous définissons une classe pour chaque palier, plus une classe pour les revenus invalides (négatifs) :
- D1 : {0 ≤ d < 20 000} (Pas d'impôt)
- D2 : {20 000 ≤ d < 30 000} (10%)
- D3 : {30 000 ≤ d < 40 000} (25%)
- D4 : {40 000 ≤ d < 55 000} (45%)
- D5 : {55 000 ≤ d < 75 000} (50%)
- D6 : {75 000 ≤ d} (55%)
- D7 : {d < 0} (Valeur invalide)
Jeu de test avec valeurs frontières : Selon le document source, le jeu de test propose de tester les limites inférieures et supérieures (ou juste en dessous) de chaque palier : {-1, 0, 19 999, 20 000, 29 999, 30 000, 39 000, 40 000, 54 999, 55 000, 74 999, 75 000}
Note de correction : Le corrigé source indique 39 000 comme limite supérieure de la classe D2. Il s'agit très probablement d'une erreur typographique dans le document original, la suite logique dictant 39 999 (à l'image de 19 999, 29 999, etc.). Toutefois, par respect pour le texte source, la valeur 39 000 y figure bien. En examen réel, écrivez 39 999.
Exercice 2 - Procédure Triangle
L'application prend trois entiers positifs (a, b, c) et identifie le type de triangle.
Définition des classes (Solution de base)
Le domaine d'entrée D est séparé selon le type de triangle :
- D1 : {(a, b, c) | a, b, c forment un triangle équilatéral}
- D2 : {(a, b, c) | a, b, c forment un triangle isocèle}
- D3 : {(a, b, c) | a, b, c forment un triangle scalène (quelconque)}
- D4 : {(a, b, c) | a, b, c ne forment pas un triangle}
Solution raffinée
Pour un test exhaustif, il faut distinguer les différentes permutations des côtés.
- Équilatéral :
- D1 = {(a, b, c) | a = b = c}
- Isocèle (3 cas de figure) :
- D21 = {(a, b, c) | a = b, a ≠ c}
- D22 = {(a, b, c) | a = c, b ≠ c}
- D23 = {(a, b, c) | b = c, a ≠ b}
- Scalène :
- D3 = {(a, b, c) | a ≠ b ≠ c}
- Invalide (Inégalité triangulaire non respectée, 3 cas) :
- D41 = {(a, b, c) | a ≥ b + c}
- D42 = {(a, b, c) | b ≥ a + c}
- D43 = {(a, b, c) | c ≥ a + b}
Jeu de test exhaustif
| N° | (a, b, c) | Classe ciblée | Type attendu |
|---|---|---|---|
| 1 | (3, 3, 3) | D1 | Équilatéral |
| 2 | (2, 2, 3) | D21 | Isocèle |
| 3 | (2, 3, 2) | D22 | Isocèle |
| 4 | (3, 2, 2) | D23 | Isocèle |
| 5 | (3, 4, 5) | D3 | Scalène |
| 6 | (6, 3, 3) | D41 | Invalide (6 ≥ 3+3) |
| 7 | (3, 6, 3) | D42 | Invalide (6 ≥ 3+3) |
| 8 | (3, 3, 6) | D43 | Invalide (6 ≥ 3+3) |
Exercice 3 - Application de réservation de golf
Nous devons définir les classes d'équivalence pour trois paramètres d'entrée distincts.
Nom d'utilisateur (String)
La gratuité dépendant (selon l'énoncé source) du fait d'être membre, le système doit différencier un utilisateur valide d'un utilisateur invalide ou inconnu.
- Classes :
- D1 = {golfeurlogin} (Un compte valide)
- D2 = {d | d ≠ golfeurlogin}
- Jeu de test (DT) : (golfeurlogin), (fajdlkjfka)
Journée
Le golf est fermé lundi et mardi, et ouvert les autres jours.
- Classes :
- D1 = {lundi, mardi} (Jours de fermeture)
- D2 = {mercredi, jeudi, vendredi, samedi, dimanche} (Jours d'ouverture)
- Jeu de test (DT) : (lundi), (mercredi)
Heures
L'ouverture se fait de 7h00 à 21h00, mais la dernière heure n'est pas prise en compte pour la réservation (donc max 20h00). Après 18h00, c'est gratuit pour les membres.
- Classes :
- D1 = {d | d < 7 ou d > 20} (Heures invalides/fermées)
- D2 = {d | 18 ≤ d ≤ 20} (Heures valides gratuites)
- D3 = {d | 7 ≤ d < 18} (Heures valides payantes)
- Jeu de test (DT) aux frontières :
- Autour de 7h00 : 6:50 (D1), 7:00 (D3)
- Autour de 18h00 : 17:50 (D3), 18:00 (D2)
- Autour de 20h00 : 19:50 (D2), 20:00 (D2 ou D1 selon l'inclusion stricte de la dernière minute. Le corrigé met 20:00 dans les limites testées).
Exercice 4 - Graphe de contrôle et couverture
L'algorithme calcule la division entière de x par y par soustractions successives, en gérant le signe.
a) Nœuds du graphe de contrôle
Bien que le graphe ne puisse être dessiné ici, voici la numérotation des nœuds implicite dans le corrigé :
- 1 : lire(x), lire(y), z = 0, signe = 1
- 2 : si x < 0
- 3 : signe = -1
- 4 : x = -x
- 5 : si y < 0
- 6 : signe = -signe
- 7 : y = -y
- 8 : tant que x >= y
- 9 : x = x - y
- 10 : z = z + 1
- 11 : z = signe * z
- 12 : fin (ou retour implicite)
b) Couverture des instructions
Le but est d'exécuter chaque ligne de code au moins une fois.
- Chemin : 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> 12
- Explication : Il faut forcer le passage dans
x < 0, dansy < 0, et dans la bouclex >= y. - Jeu d'essai minimum : (x = -5, y = -2)
c) Couverture des arcs
Le but est de traverser toutes les branches possibles (Vrai et Faux pour chaque condition).
- Chemins requis :
1 2 5 8 11 12: x positif (saute 3,4), y positif (saute 6,7), x < y (ne rentre pas dans la boucle).1 2 3 4 5 6 7 8 9 10 11 12: x négatif, y négatif, rentre dans la boucle.
- Jeu d'essai minimum : (x = 2, y = 5) et (x = -5, y = -2)
d) Couverture des i-chemins (1-chemin)
Il faut tester les chemins en répétant 0 fois, puis 1 fois chaque boucle. Note sur la correction source : Les chemins donnés par le corrigé pour 1 itération ne montrent pas explicitement la remontée vers le nœud 8 (condition de boucle). Un chemin strict serait 8 -> 9 -> 10 -> 8 -> 11. Le corrigé source l'abrège en 8 -> 9 -> 10 -> 11 -> 12. Nous reproduisons fidèlement la logique du corrigé ci-dessous.
Chemins et Jeux d'essai :
-
Boucle 0 fois (x < y) :
1 2 5 8 11 12(x>0, y>0) -> Jeu : (x = 2, y = 5)1 2 3 4 5 8 11 12(x<0, y>0) -> Jeu : (x = -2, y = 5)1 2 5 6 7 8 11 12(x>0, y<0) -> Jeu : (x = 2, y = -5)1 2 3 4 5 6 7 8 11 12(x<0, y<0) -> Jeu : (x = -2, y = -5)
-
Boucle 1 fois (x >= y, puis x - y < y) :
1 2 5 8 9 10 11 12-> Jeu : (x = 5, y = 2)1 2 3 4 5 8 9 10 11 12-> Jeu : (x = -5, y = 2)1 2 5 6 7 8 9 10 11 12-> Jeu : (x = 5, y = -2)1 2 3 4 5 6 7 8 9 10 11 12-> Jeu : (x = -5, y = -2)
Exercice 5 - Comparaison des critères de couverture
1. Graphes de contrôle
(À modéliser mentalement d'après le code :)
- P1 : Un bloc de décision
x < 0. Si vrai, exécutex := -x, puis rejoint la suitez := x. - P2 : Un premier bloc
if not(x=0)qui bifurque soit sury:=5, soit surz := z - x. Les deux branches se rejoignent, puis un second blocif (z > 1)bifurque surz := z / xouz := 0.
2. Couverture instructions vs arcs sur P1
Le test (x = -2) passe dans la condition x < 0, exécute x := -x et z := x.
Toutes les instructions de P1 sont exécutées. Cependant, la couverture des arcs n'est pas complète car la transition qui "saute" le bloc x := -x (le cas où la condition est fausse) n'est jamais empruntée.
- Conclusion : Il faudrait ajouter un test avec un nombre positif (ex: x = 2) pour couvrir l'arc correspondant à la condition fausse.
3. Couverture arcs vs chemins sur P2
Considérons le jeu de test suivant : (x = 0, z = 1) et (x = 1, z = 3)
- Pour
(x = 0, z = 1):x=0est vrai, doncnot(x=0)est Faux -> branchez := z - xévaluée (z devient 1). Ensuite,z > 1(1 > 1) est Faux -> branchez := 0évaluée. - Pour
(x = 1, z = 3):x=1est vrai, doncnot(x=0)est Vrai -> branchey := 5évaluée. Ensuite,z > 1(3 > 1) est Vrai -> branchez := z / xévaluée.
Ce jeu d'essai parcourt bien toutes les branches (arcs) possibles (Vrai et Faux de chaque if).
Cependant, il ne couvre pas toutes les combinaisons (chemins). Par exemple, le chemin croisant "branche Else du premier If" suivie de "branche Then du second If".
- Si ce chemin manquant était testé (par exemple avec
x = 0etz = 3), le programme exécuteraitz := z - 0(z reste 3), puis vérifieraitz > 1(Vrai), et tenteraitz := z / xsoit3 / 0, causant une division par zéro. - Jeu couvrant tous les chemins : (x=0, z=3), (x=1, z=1), (x=0, z=1), (x=1, z=3).
Exercice 6 - Programme P3
Avertissement : Les questions de l'Exercice 6 sont présentes dans le document source (Calculer les DT suivant les critères tous-les-nœuds, tous-les-arcs, tous-les-chemins-indépendants), mais la correction officielle de cet exercice est absente du document original fourni, qui saute directement à la solution de l'Exercice 7. Par conséquent, il est impossible de reproduire le corrigé officiel de cette question.
Exercice 7 - Calcul de la complexité et couverture
1 : Function (a, b)
2 : If (a < 10)
3 : c := a + b
4 : a := a + 1
5 : If (b > 10)
6 : d := a - b
7 : b := b - 1
8 : EndIf
9 : EndIf
10: EndFunction
Couverture des instructions
Il faut atteindre l'intérieur du If imbriqué (lignes 6-7).
- Conditions requises : a < 10 et b > 10.
- Jeu de test : (a = 5, b = 15)
Couverture des arcs
Il faut traverser toutes les branches (vrai/faux) de chaque condition.
- (5, 5) : a < 10 (Vrai) mais b > 10 (Faux)
- (20, 5) : a < 10 (Faux)
- (5, 15) : a < 10 (Vrai) et b > 10 (Vrai)
- Jeu de test : (5, 5), (20, 5), (5, 15)
Couverture des chemins indépendants
La formule de la complexité cyclomatique est : e - v + 2
- Selon le corrigé : e = 8 (arcs), v = 7 (nœuds)
- Complexité : 8 - 7 + 2 = 3 chemins indépendants.
- Jeu de test : Les trois tests trouvés pour les arcs suffisent ici : (5, 5), (20, 5), (5, 15)
Exercice 8 - Graphe de flot de contrôle complexe
1 : Fonction( int a, int b, int c)
2 : d := a+b+c
3 : if ( a = b )
4 : d := d*2
5 : else if (a = c)
6 : d = d/2
7 : else
8 : d = a
9 : endif
10: endif
11: while ( c > 10)
12: d := d+b+a
13: c := c-1
14: if (b > a)
15: d := d*5;
16: endif
17: endwhile
18: endFunction
a) Couverture des instructions
Note : Le document source marque cette section "(à revoir)". Pour couvrir toutes les instructions, il faut atteindre l'intérieur du Else (ligne 8), l'intérieur du premier If (ligne 4), et l'intérieur du Else If (ligne 6). Il faut aussi entrer dans la boucle while et valider son If interne.
- D1 : {(a,b,c) | b > a, c > 10, c ≠ a} (Cible le Else (a≠b, a≠c) et le If dans le while)
- D2 : {(a,b,c) | a = b} (Cible le premier If)
- D3 : {(a,b,c) | a ≠ b, a = c} (Cible le Else If)
- Jeu de test : (5, 10, 20), (5, 5, 5), (5, 10, 5)
b) Couverture des arcs
Il faut traverser toutes les conditions, incluant le contournement du If dans le While (lorsque b ≤ a).
- D1 : {(a,b,c) | a = b, c > 10}
- D2 : {(a,b,c) | b > a, c = a, c > 10}
- D3 : {(a,b,c) | b > a, c ≠ a, c > 10}
- Jeu de test : (5, 5, 15), (15, 10, 15), (15, 10, 20)
Méthode
Face à une épreuve de conception de tests (Test du Logiciel, Génie Logiciel) :
- Graphe de contrôle avant tout : Pour le test structurel (boîte blanche), numérotez systématiquement les lignes ou instructions pour tracer l'arbre des chemins. Repérer les
if,while, etforpermet de compter instantanément le nombre de chemins indépendants via la formule cyclomatique. - Attention aux défauts des arcs : Comme vu dans l'Exercice 5, satisfaire la couverture des instructions est une condition faible. Pensez toujours aux embranchements "invisibles", c'est-à-dire l'absence de
else. Il faut un test pour exécuter le code, et un test pour vérifier ce qui se passe quand le code est ignoré. - Frontières des domaines : Pour le test fonctionnel (boîte noire, Exercices 1 et 3), les erreurs de code se cachent dans les inégalités strictes ou larges (
<vs≤). Ne vous contentez pas d'une valeur au milieu d'un palier, testez toujours les deux limites exactes de ce palier. - Combinatoire : Lorsque plusieurs variables entrent en jeu (a, b, c pour un triangle), ne faites pas varier toutes les données d'un coup. Le raffinement des classes d'équivalence de l'Exercice 2 montre qu'il faut fixer certaines variables tout en modifiant les autres pour isoler l'origine potentielle d'un bug.
Commentaires
Aucun commentaire pour le moment. Posez la première question.