Rien n'est plus déterminant pour la satisfaction des utilisateurs envers le logiciel qu'une analyse précise de leurs
attentes en vue de les vérifier et de les valider. Les cas de test reflètent les exigences à contrôler. Toutefois,
cette vérification peut être effectuée de diverses manières et par plusieurs testeurs. Par exemple, l'exécution du
logiciel pour en vérifier le fonctionnement et les performances peut être faite par un testeur appliquant des
techniques de test automatisées ; pour sa part, la séquence d'arrêt d'un système peut être vérifiée par un test manuel
et une observation, alors que la part de marché et les ventes (également des exigences du produit) pourront être
analysées en mesurant les ventes du produit et de la concurrence.
Comme vous ne pourrez pas ou ne serez pas chargé de vérifier toutes les exigences, il est indispensable de sélectionner
celles qui sont les plus appropriées ou pertinentes à tester afin d'assurer la réussite de votre projet. Les exigences
choisies pour vérification seront un compromis entre le coût, le risque et le besoin de mener cette vérification.
Il est important d'identifier les cas de test pour plusieurs raisons.
-
Ils sont la base à partir de laquelle sont conçus et développés les scripts de test.
-
La profondeur d'un test est proportionnelle au nombre de cas de test. La confiance dans la qualité du produit et le
processus de test augmentera avec le nombre de cas de test, sachant que chacun d'eux illustre un scénario, une
condition ou un flux distinct au sein du produit.
-
La principale mesure de la complétude d'un test est la couverture des exigences, par rapport au nombre de cas de
test identifiés, implémentés et/ou exécutés. Affirmer que 95 % des principaux cas de test ont été faits et vérifiés
est plus convaincant que le fait d'être à 95 % de l'ensemble des tests.
-
L'échelle de l'effort de test est proportionnelle au nombre de cas de test. Grâce à une présentation détaillée des
cas de test, il est possible d'évaluer plus précisément la durée de chaque phase du cycle de test.
-
Les types de conception et de développement de tests ainsi que les ressources nécessaires dépendent en grande
partie des cas de test.
Les cas de test sont souvent classés par type de test ou exigence de test auxquels ils sont associés et varient en
conséquence. La pratique consiste à développer au moins deux cas de test pour chaque exigence :
-
Un cas de test démontrant que l'exigence a été satisfaite. Il s'agit alors d'un cas de test positif.
-
Un autre cas de test illustrant une condition ou une donnée inacceptable, anormale ou inattendue, afin de démontrer
que l'exigence est uniquement satisfaite dans la condition souhaitée. Il s'agit alors de cas de test négatifs.
Le test d'unité requiert de tester la structure interne de l'unité et ses caractéristiques comportementales. Pour
tester la structure interne, vous devez savoir comment l'unité est implémentée et les tests s'appuyant sur cette
connaissance sont dits structurels. Le test des caractéristiques comportementales de l'unité se centre sur les
comportements externes observables de l'unité sans rien savoir de son implémentation. Les tests réalisés selon cette
approche sont qualifiés de fonctionnels. La création de cas de test selon ces deux approches est décrite ci-après.
En théorie, vous devez tester les moindres recoins du code. Cette mission est peu réaliste ou impossible dans toutes
les unités qui ne sont pas extrêmement simples. Vous devez vérifier au moins une fois tous les chemins entre
décisions, ce qui permet également d'exécuter au moins une fois toutes les instructions. Une décision est
généralement une instruction if et un chemin relie deux décisions.
Pour obtenir ce niveau de couverture, il est conseillé de choisir des données de test pour que chaque décision soit
évaluée de toutes les façons possibles. A cette fin, les cas de test doivent assurer que :
-
chaque expression booléenne est évaluée à true et false. Par exemple, l'expression (a<3) OR
(b>4) évalue les quatre combinaisons de true/false.
-
chaque boucle sans fin est contrôlée au moins zéro fois, une fois et plus d'une fois.
Servez-vous des outils de couverture du code pour identifier le code non vérifié par le test structurel. Un test de
fiabilité doit être effectué en même temps que le test structurel.
Exemple :
Imaginez que vous réalisez un test structurel pour une fonction membre de la classe Ensemble d'entiers.
Grâce à une recherche binaire, le test vérifie si l'ensemble contient un entier déterminé.
La fonction membre et le diagramme de flux correspondant. Les flèches en pointillés illustrent comment utiliser deux
cas de test pour exécuter toutes les instructions au moins une fois.
En théorie, pour qu'une opération soit testée en détail, le cas de test doit couvrir toutes les combinaisons de
parcours dans le code. Dans le membre, il existe trois parcours distincts à l'intérieur de la boucle
while. Le cas de test peut traverser la boucle plusieurs fois ou pas du tout. Dans le second cas, vous ne trouverez
qu'un seul parcours au sein du code. Si la boucle est traversée une seule fois, vous aurez trois parcours. Si elle est
traversée deux fois, vous aurez six parcours, et ainsi de suite. Par conséquent, le nombre total de parcours sera
1+3+6+12+24+48+..., ce qui est en pratique un nombre de combinaisons ingérable. C'est pourquoi vous devez choisir un
sous-ensemble de ces parcours. Dans cet exemple, vous pouvez utiliser deux cas de test pour exécuter toutes les
instructions. Dans l'un d'eux, choisissez Ensemble d'entiers = {1,5,7,8,11} et t =
3 comme données de test. Dans l'autre, choisissez Ensemble d'entiers = {1,5,7,8,11} et
t = 8 .
Voir Technique : Test d'unité pour en savoir plus.
Tests fonctionnels
L'objectif d'un test fonctionnel est de vérifier le comportement indiqué de l'unité sans s'intéresser à la façon
dont l'unité implémente ce comportement. Les tests fonctionnels se centrent et s'appuient sur l'entrée et la sortie de
l'unité.
Le partitionnement en classes d'équivalence est une technique permettant de réduire le nombre de tests requis.
Pour chaque opération, vous devez identifier les classes d'équivalence des arguments et les états des objets. Une
classe d'équivalence est un ensemble de valeurs pour lesquelles un objet est censé se comporter de la même
façon. Par exemple, un Ensemble possède trois classes d'équivalence : vide, un élément et
plein.
Servez-vous des outils de couverture du code pour identifier le code non vérifié par le test structurel. Un test de
fiabilité doit être effectué en même temps que le test fonctionnel.
Les deux sous-sections suivantes décrivent comment identifier des cas de test en sélectionnant des données de test pour
des arguments spécifiques.
Cas de test basés sur des arguments en entrée
Un argument en entrée est un argument utilisé par une opération. Vous devez créer des cas de test à l'aide
d'arguments en entrée pour chaque opération dans chacune des conditions d'entrée suivantes :
-
Valeurs normales pour chaque classe d'équivalence
-
Valeurs à la frontière de chaque classe d'équivalence
-
Valeurs en dehors des classes d'équivalence
-
Valeurs interdites
Pour rappel, vous devez considérer l'état d'objet comme un argument en entrée. Par exemple, si vous testez une
opération ajouter sur un objet Ensemble, vous devez le faire avec des valeurs de toutes les classes
d'équivalence d'Ensemble, c'est-à-dire avec un Ensemble plein, avec un élément dans l'Ensemble et
avec un Ensemble vide.
Cas de test basés sur des arguments en sortie
Un argument en sortie est un argument modifié par une opération. Un argument peut être à la fois en entrée et en
sortie. Sélectionnez l'entrée afin d'obtenir la sortie des éléments suivants :
-
Valeurs normales pour chaque classe d'équivalence
-
Valeurs à la frontière de chaque classe d'équivalence
-
Valeurs en dehors des classes d'équivalence
-
Valeurs interdites
Pour rappel, vous devez considérer l'état d'objet comme un argument en sortie. Par exemple, si vous testez une
opération supprimer sur une liste, vous devez choisir des valeurs d'entrée pour que cette liste
soit pleine, comporte des éléments ou soit vide au terme de l'opération (testez avec des valeurs issues de toutes ses
classes d'équivalence).
Si l'objet est contrôlé par son état (à savoir qu'il réagit différemment en fonction de l'état dans lequel il se
trouve), vous devez utiliser une matrice d'états telle que celle dans la figure ci-après.
Matrice d'états pour les tests. Vous pouvez tester toutes les combinaisons d'états et de stimuli par rapport à cette
matrice.
Voir Technique : Test d'unité pour en savoir plus.
|