Press "Enter" to skip to content

Modèles de typologie de tests

Photo by Karina Vorozheeva on Unsplash

Modèles de typologie de tests

Dans cet article, je vous présente différents modèles qui servent à classifier les différents types de test. Le but de ces modèles est de prendre de la hauteur et comprendre pourquoi définit-on ces différents types de test.

Cout d’exécution & délai de feedback

Un premier modèle consiste à répartir les types de tests par leur cout d’exécution et leur délai de feedback, ces deux paramètres étant souvent liés : plus un test est couteux à mettre en oeuvre, plus son exécution est généralement longue et donc son délai de feedback long.

Cout et délai de feedback selon le type de test

La pyramide de test Agile

Ce modèle est la base de la pyramide de test Agile de Mike Cohn. (lien à la fin de l’article) En rajoutant une 2e dimension pour le nombre de tests ou l’effort à fournir pour chaque catégorie de test, on obtient une pyramide :

Ajout de la proportion d’effort souhaitable pas type de test : la pyramide de test Agile de Mike Cohn

Cette métaphore de la pyramide modélise très bien les atouts d’une stratégie de test automatisée réussie :

  • Maximiser les tests qui sont à la fois les moins chers et qui fournissent un feedback le plus rapide possible
  • Il faut donc viser une excellente couverture de code par ces tests, qui forment le noyau dur de la stratégie de test
  • À l’inverse, minimiser les tests qui sont à la fois les plus couteux et avec le délai de feedback le plus long
  • Bien qu’il faille essayer de faire le moins possible de ces tests couteux, il serait dangereux de s’en passer et ils restent nécessaire

Périmètre d’un test

On peut faire une variante de la pyramide de test Agile en se focalisant plutôt sur le périmètre des différents tests. Voici un exemple de catégorisation :

En ne parlant plus de type de test mais de périmètre couvert par les tests en question
  • Fonction : typiquement un test unitaire, le test s’attarde sur une fonction, une classe, un objet
  • Composant : le test s’attarde sur un périmètre plus grand que celui d’un test unitaire, tout en restant confiné à l’intérieur d’un composant de l’architecture logicielle
  • Multiples composants : le test sort cette fois d’un composant et a un périmètre qui regroupe plusieurs composants
  • Bout en bout : le test implique l’intégralité du produit

Ces 4 niveaux sont donnés à titre indicatif. Si vous essayez d’appliquer ce modèle à votre produit, vous aurez plus ou moins de niveaux selon sa complexité et les spécificités de son architecture.

Les réflexions en termes de cout d’exécution et de délai de feedback s’appliquent tout autant à ce modèle. C’est assez logique car plus le périmètre est large, plus il y a de dépendances à prendre en compte et plus l’environnement de test est contraignant :

  • Fonction : aucun environnement, le code testé est exécuté en isolation complète
  • Composant : le code du composant est lancé intégralement, toutes les dépendances hors du composants sont simulées
  • Multiples composants : les composants testés sont lancés intégralement, seules certaines dépendances sont simulées
  • Bout en bout : il faut l’équivalent d’un environnement complet, le plus similaire possible à l’environnement de production

Conséquences d’un environnement de test complet

Plus longs à exécuter : Une dépendance simulée répond beaucoup plus vite qu’une réelle dépendance qui doit faire un calcul, effectuer des appels réseaux, accéder à une base de données…

Plus fragiles : Le résultat retourné par une dépendance simulée est complètement déterministe. Une dépendance non simulée peut retourner des résultats variables, ou dépendant de conditions externes non-maîtrisables ou trop coûteuses à maîtriser.

Plus coûteux : Un environnement de test complet utilise des serveurs dédiés le temps du test.

En modélisant les contraintes d’environnement, dont découlent le cout et le délai de feedback

La variante pragmatique de Google

Le livre How Google Tests Software (lien à la fin de l’article) présente une vision alternative qui simplifie la catégorisation des tests : Small, Medium et Large.

En plus de proposer une classification très facile à appréhender, cette approche est très orientée vers les tests automatisés et leur utilisation au sein de l’intégration continue. (lien à la fin de l’article) Google met un accent très prononcé sur l’automatisation et la durée d’exécution d’un test est un élément important de sa classification.

Quand on y regarde de plus près, on voit que ces notions se combinent et dans le cas de Google, le contexte d’exécution du test s’assure même qu’ils sont respectés :

  • En fonction de la taille du test, plus ou moins de dépendances sont permises (leur instanciation est programmatiquement interdite selon la taille du test)
  • La durée d’exécution d’un test est bornée en fonction de la taille du test

Rôle d’un test

Une autre manière de classer les différentes catégories de test est selon son rôle. Que testent les tests de cette catégorie ?

Voici un modèle qui consiste à séparer les tests en deux grands pans :

  • Tests de comportements
  • Tests d’intégration

Tests de comportements vs. tests d’intégration

Tests de comportements : Un test de comportement vérifie que le système retourne la bonne réponse. Ce test sera fragile si le calcul de la réponse n’est pas complètement déterministe.

Tests d’intégration : Un test d’intégration vérifie que le système retourne une réponse. Ce test sera plus robuste qu’un test de comportements face à des réponses non déterministes.

Exemple simpliste d’une calculatrice :

1. Test de comportements : Vérifier que 5+3 donne 8

2. Test de comportements : Vérifier que 2×3 donne 6

3. Test d’intégration : Vérifier que 4+2×5 donne un résultat

Ce modèle permet de définir une première typologie de test en le conjuguant avec celui qui classe par périmètre de test :

Périmètre vs. rôle : création naturelle d’une première typologie de tests

L’intérêt de ce modèle est qu’il donne un bon canevas pour réfléchir à la couverture de code par les tests.

Ainsi l’utilisation des 5 types de test donnés dans l’exemple permet d’avoir une couverture satisfaisante en jouant sur les tests de comportements et d’intégration des différents niveaux de périmètre testé :

  • Tester exhaustivement la combinatoire des comportements avec les tests unitaires
  • Tester exhaustivement l’intégration interne au composant avec les tests d’assemblage
  • Tester les scenarios les plus critiques (nominaux, cas d’erreurs classiques) avec les tests fonctionnels
  • Tester simplement l’intégration du composant avec les autres composants avec les tests d’intégration
  • Si la nouvelle fonctionnalité n’est pas déjà couverte par les tests E2E existants et qu’elle est considérée suffisamment critique, alors ajouter un nouveau test de bout en bout, on s’intégrer dans un déjà existant

Ce découpage respecte la structure de pyramide qui favorise l’écriture de tests peu coûteux tout en ne négligeant pas l’écriture des tests dans un environnement plus proche de la production.

L’utilisation des tests d’intégration en complément des tests de comportements permet d’optimiser à la fois la couverture et l’effort de test :

  • On teste exhaustivement la combinatoire avec des tests de comportement sur un périmètre le plus petit possible
  • Les tests d’intégration permettent d’écrire des tests dans des environnements plus complets tout en étant robustes car ils ne vérifient pas le détail des données

Outil de rédaction : qui doit pouvoir comprendre le test ?

Lorsqu’un test de non-régression échoue, cela n’indique pas toujours une régression. Cela peut aussi indiquer un impact non anticipé, provoqué par un changement ailleurs sur le produit. (lien à la fin de l’article)

Comment déterminer s’il s’agit d’une régression ou d’un impact non anticipé ?

Qui sait dire pourquoi le test échoue ? Technique ou métier ?

Si le test concerne une exigence technique, un développeur sera certainement la bonne personne pour répondre à cette question.

Si par contre le test concerne une exigence métier, ce sera plutôt un expert métier qui aura la réponse à la question.

Or, pour pouvoir donner une réponse, encore faut-il comprendre la question. Il faut pouvoir comprendre le test qui échoue pour pouvoir dire s’il s’agit d’une régression ou d’un impact non anticipé.

Quel outil utiliser pour faire en sorte que l’énoncé du test soit compréhensible ?

S’il s’agit d’un test technique, qui concerne une exigence technique, l’utilisation de code est idéale pour exprimer le test. Le développeur comprend le code, et l’utilisation directe de code donne à la fois un maximum de flexibilité et de meilleures performances d’exécution.

Si par contre il s’agit d’un test métier, qui concerne une exigence métier, on voudra alors utiliser un langage pseudo-naturel pour pouvoir exprimer le test sous une forme qui permettra d’impliquer les experts métier. On parle de rédiger des spécifications exécutables. (lien à la fin de l’article) Dans ce cas de figure, des outils spécifiques imposent un surcout supplémentaire à la création et à l’exécution mais celui-ci est largement compensé par l’intérêt d’impliquer directement les experts métier.

Combinaison avec le périmètre des tests

Selon ce modèle, on voit que les tests définis sous forme de spécifications exécutables ne sont pas nécessairement des tests système, qui se placent au niveau d’un utilisateur, ou qui manipulent l’interface graphique.

On conçoit très bien que des règles métier complexes puissent être implantées au niveau le plus bas du code. Dans cette logique, on voudrait rédiger des tests pour ces règles métier, sous forme de spécifications exécutables en impliquant fortement les experts métier. En pratique, la mise en place de ces tests ressemblerait fortement à l’implantation de tests unitaires.

Pour aller plus loin

La pyramide de test de Mike Cohn

How Google Tests Software

Les ingénieurs de Google (la couverture du livre cite James A. Whittaker, Jason Arbon and Jeff Carollo en tant que contributeurs principaux mais le livre est en réalité le travail de nombreux ingénieurs de Google) décrivent dans “How Google Tests Software” comment Google a radicalement changé la manière dont ils travaillent afin de s’assurer de la qualité à tous les niveaux avec un effort minimal de maintenance manuelle. Ils révèlent comment travaille Google de manière totalement transparente et directe, aussi la lecture de ce livre vous donnera un maximum d’information en un minimum de temps de lecture. Même si votre organisation n’a aucun espoir de devenir du calibre de Google (combien d’entreprises pourraient nourrir cette vision ?) vous pouvez toujours sélectionner et ré-utiliser de nombreuses idées ici et là. Au grand minimum, ce livre vous fera réfléchir et remettre en question votre manière de travailler, tout en vous suggérant des idées à essayer.

Introduction à l’intégration continue

https://youtu.be/70LqFphGmC8

Qu’est-ce qui se cache derrière un test qui échoue ?

Rédaction des spécifications exécutables

Que pensez-vous de cet article?

J’apprécierais vraiment si vous pouviez me laisser un commentaire pour me dire ce que vous appréciez ou ce qui pourrait être amélioré dans cet article.

Et si vous avez aimé cet article, merci d’applaudir 👏 et de le partager !

À bientôt 😊

Top