Découvrez comment intégrer facilement l'analyse statique, les tests unitaires et d'autres méthodes de test de logiciels C et C++ dans votre pipeline CI/CD. Inscrivez-vous pour la démo >>

Mesures de couverture de test unitaire

Par Parasoft

24 août 2011

3  min lire

Indépendant du granularité de la couverture, il existe un certain nombre de critères de couverture différents qui prennent en compte différents aspects de la couverture.

La portée des différents critères de couverture sera illustrée à l'aide de la méthode Java présentée dans le listing 2. L'exemple de méthode n'effectue aucune opération pratique, mais elle est assez simple et très utile pour illustrer tous les critères de couverture abordés dans cet article. Pour des raisons de simplicité, la méthode testée n'a qu'un seul paramètre d'entrée. Cependant, comme une méthode avec deux paramètres peut également être considérée comme une méthode avec un paramètre qui se trouve être une paire ou un tuple, les concepts abordés dans cet article s'appliquent tout aussi bien aux méthodes avec plusieurs paramètres.

Couverture de l'état

Le critère de couverture le plus élémentaire est la couverture des déclarations (parfois également appelée «couverture par bloc»). Une couverture complète des instructions est obtenue lorsque chaque instruction d'une méthode testée est exécutée par au moins un scénario de test. Pour l'exemple de méthode du Listing 2, deux cas de test, utilisant les valeurs d'entrée 0 et 1, sont suffisants pour obtenir une couverture complète des instructions. Un test JUnit correspondant est présenté dans le Listing 3. Le corps de la première instruction if sera exécuté pour les deux entrées.

La couverture de l'instruction ne prend pas en compte ce qui se passerait si la condition de la première instruction if était évaluée à false, auquel cas le corps de la première instruction if n'était pas exécuté. En pratique, il est tout aussi important de considérer ce qui se passe lorsqu'un certain morceau de code n'est pas exécuté. Le test de telles situations doit aller au-delà de la simple vérification que chaque instruction a été exécutée.

Classe publique Listing2 {méthode int statique publique [] (entrée d'octet) {condition booléenne1 = (entrée & 1) == 0; booléen condition2 = (entrée & 2) == 0; sortie int = -1; if (condition2) {sortie ++; } if (condition1) {return null; } else {return new int [sortie]; }}}

Liste 2: Exemple de méthode Java pour démontrer différents critères de couverture

public class Listing3 étend junit.framework.TestCase {public void testMethod0 () {int [] result = Listing2.method ((byte) 0); assertNull (résultat); } public void testMethod1 () {int [] result = Listing2.method ((byte) 1); assertEquals (0, result.length); }}

Liste 3: Exemple de scénario de test JUnit qui fournit une couverture d'instruction à 100% pour le Listing 2

Couverture de la succursale

Le critère de couverture qui prend en compte ces situations est appelé couverture de branche (également appelée couverture de condition ou couverture de décision). Une couverture de branche complète nécessite que tous les résultats possibles d'une expression conditionnelle soient exécutés par un scénario de test. Pour l'exemple de méthode, cela signifie qu'il doit y avoir une entrée de test où condition2 (dans la première instruction if) prend la valeur false et où le corps de la première instruction if est donc ignoré. Pour obtenir une couverture de branche de 100% pour l'exemple de méthode, vous pouvez ajouter un troisième scénario de test qui utilise une valeur d'entrée de 2. Le scénario de test qui utilise 0 comme entrée serait redondant dans ce scénario. Si les entrées de test sont choisies avec soin, vous pourrez peut-être obtenir une couverture de branche complète avec le même nombre d'entrées. Cependant, ce n'est pas une règle générale et vous aurez peut-être besoin de plus de scénarios de test pour atteindre la couverture de succursale que vous n'en avez besoin pour atteindre la couverture des relevés.

Couverture de chemin

La couverture de 100% des succursales garantira-t-elle qu'un morceau de code est exempt de bogues? Bien qu'elle présente une amélioration significative par rapport à la simple couverture des relevés, la couverture complète des succursales ne fournit toujours aucune garantie qu'un morceau de code se comporte toujours correctement.

L'exemple de méthode du listing 2 peut en fait lever une NegativeArraySizeException dans certaines circonstances. Ce problème se produit pour toutes les entrées où le corps de la première instruction if est ignoré car condition2 est évalué à faux et en même temps condition1 est également évalué à faux. Dans ces cas, le code tentera d'allouer un tableau de taille -1. La couverture de branche couvre les deux alternatives de la seconde instruction if, mais elle ne garantit pas que la branche else de l'instruction est couverte en combinaison avec le corps de la première instruction if ignorée.

Pour couvrir de telles situations, nous devons examiner des combinaisons de branches, également appelées chemins de code. Ce critère de couverture est appelé couverture de chemin. La couverture de chemin nécessite non seulement que chaque branche possible soit exécutée au moins une fois, mais également que chaque combinaison possible de branches soit exécutée au moins une fois.


Figure 1: Diagramme d'activité UML avec chemins de code possibles via l'exemple de méthode

La figure 1 montre le flux de contrôle de l'exemple de méthode de la liste 2 sous forme de diagrammes d'activité UML. Dans chaque diagramme, un chemin de code différent est mis en évidence en rouge gras. L'exemple de méthode a un total de quatre chemins de code différents. Pour atteindre une couverture de chemin à 100%, vous avez besoin d'un minimum de quatre cas de test différents (par exemple, en utilisant les valeurs d'entrée 0, 1, 2 et 3).

Par Parasoft

Les outils de test de logiciels automatisés de pointe de Parasoft prennent en charge l'ensemble du processus de développement logiciel, depuis le moment où le développeur écrit la première ligne de code jusqu'aux tests unitaires et fonctionnels, jusqu'aux tests de performance et de sécurité, en exploitant des environnements de test simulés en cours de route.

Recevez les dernières nouvelles et ressources sur les tests de logiciels dans votre boîte de réception.