• 10 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 20/09/2024

Découvrez les tests d'intégration et les tests fonctionnels

Les deux premières parties étaient consacrées aux tests unitaires. Il est temps de gravir la pyramide des tests après s'être forgé des bases solides. Mais vous souvenez-vous pourquoi nous devons écrire d'autres types de tests ? Sachez que les développeurs aussi ont de l'humour, et comme une image vaut mieux qu'un long discours :

Image montrant un test d'intégration qui échoue
Une prise électrique OK. Un distributeur de savon OK. Utiliser l'ensemble : ERREUR !

Gravissez la pyramide : les tests d'intégration et les tests fonctionnels (ou end-to-end)

Jusqu’ici, nous avons vérifié des composants individuels. Mais cela signifie que nous avons émis beaucoup de suppositions sur la façon dont ces éléments fonctionnent ensemble, surtout en utilisant des mocks dès que la classe à tester avait besoin d'un autre composant. Nous devons maintenant nous assurer que le comportement de l'application est toujours aussi conforme, à mesure que nous assemblons les unités de code. Pour cela, nous allons utiliser les tests qui se trouvent au milieu de la pyramide, les tests d'intégration, et les tests au sommet de la pyramide, c'est-à-dire les tests fonctionnels.

Pyramide des tests
Pyramide des tests

Sachez qu'il existe deux types de tests d'intégration : les tests d'intégration composants et les tests d'intégration système :

  • les tests d'intégration composants : ils permettent de vérifier si plusieurs unités de code fonctionnent bien ensemble, dans un environnement de test assez proche du test unitaire, c'est-à-dire de manière isolée, sans lien avec des composants extérieurs et ne permettant pas le démarrage d'une vraie application ;

  • les tests d'intégration système : ils permettent de vérifier le fonctionnement de plusieurs unités de code au sein d'une configuration d'application, avec éventuellement des liens avec des composants extérieurs comme une base de données, des fichiers, ou des API en réseau.

Passons aux tests fonctionnels de bout en bout. Ce sont des tests qui partent de l'interface utilisateur pour obtenir un résultat selon un scénario prédéfini. Ils imitent l'utilisateur final de l'application. Un démarrage complet de l'application est donc nécessaire.

Ce tableau ci-dessous donne quelques exemples de chaque type de test, afin de vous aider à mieux les distinguer.

Pyramide

Test

Question à laquelle on répond

Exemple

Milieu

Tests d’intégration composants

Est-ce que les classes que nous avons soumises aux tests unitaires fonctionnent vraiment bien ensemble ?

Nous écrivons un test JUnit qui vérifie que  BatchCalculatorService  peut appeler des méthodes sur  CalculatorService  et  Calculator, et pour vérifier des bons et mauvais chemins représentatifs entre ces deux classes.

Milieu

Tests d’intégration système (SIT pour « System Integration Tests »)

Comment pouvons-nous rapidement tester que notre application en fonctionnement collaborerait avec le monde extérieur ?

  • Un test qui utilise un de nos services pour écrire à une base de données réelle.

  • Un test pour une classe qui parle à un autre service, comme l’API de Google Search. Pour le rendre rapide, nous parlerions à un faux service, ou un "bouchon" avec des réponses réalistes.

  • Un test qui vérifie que notre configuration Spring fonctionne et que notre application pourra se lancer.

  • Des tests des contrôleurs de notre service web avec des requêtes simulées mais semblant réelles.

Sommet

Tests du parcours utilisateur de bout en bout

Comment pouvons-nous vérifier qu'un utilisateur final utilisera une application conforme et cohérente de bout en bout ?

  • Tester qu’un utilisateur peut se loguer dans notre système, sélectionner un type de calcul, entrer des valeurs, et les convertir correctement.

À chaque usage un type de test. Posez-vous la question suivante : de quel test ai-je vraiment besoin dans mon cas ? Dans les quelques chapitres à venir, nous verrons comment écrire et implémenter chacun de ces tests à tour de rôle.

Découvrez les tests d’acceptation durant votre ascension

En complément des tests d'intégration et des tests fonctionnels, vous pouvez effectuer des tests d'acceptation. Ils abordent un autre point de vue : il s'agit de vérifier directement une exigence métier, exprimée par le client, un expert fonctionnel le représentant.

Mais attends, ils n'apparaissent pas dans la pyramide que j'ai vue plus haut !

Eh non, traditionnellement, les tests d’acceptation manuels étaient les derniers à être testés, et toujours au sommet de la pyramide sur un système qui fonctionne. C’était "avant". Certains pensent que leur place est toujours là dans le monde automatisé, mais les tests manuels effectués à la fin sont extrêmement lents.

C'est pour cette raison que de nombreuses équipes choisissent d'écrire des tests d'acceptation qui se trouvent au même niveau de la pyramide que les tests d'intégration.

Les frameworks modernes, tels que Spring et Cucumber, facilitent leur écriture dans cette configuration.

Je ne comprends pas. Au milieu de la pyramide, il n’y a pas de système complètement fonctionnel ! Cela signifie que nous en sommes encore à émettre des suppositions sur l’utilisateur. Ne devrions-nous pas utiliser uniquement des tests de bout en bout ? 🤔

À la base, les tests d’acceptation peuvent être implémentés de plus d’une façon. Vous n’avez pas besoin d’utiliser exclusivement des tests de bout en bout. De fait, il est peu probable que vous le fassiez. Martin Fowler, l’un des fondateurs du mouvement Agile et qui soutient l'approche de la pyramide de test, décrit les tests d’acceptation de façon transversale à la pyramide de test :

« Il est bon de comprendre qu’il n’y a pas de nécessité technique à écrire les tests d’acceptation au sommet de la pyramide de test. Si la conception de votre application et le scénario en cours vous permettent d’écrire un test d’acceptation à un niveau inférieur, allez-y. Il est préférable de disposer d’un test de bas niveau plutôt que d’un test de haut niveau. »

Autrement dit, vos tests d'acceptation doivent se dérouler aussi vite que possible, et vous devez utiliser des tests automatisés au niveau le plus bas possible de la pyramide.

Ainsi, vous obtiendrez un feedback rapide et fiable. Ces tests ne sont peut-être pas au même niveau de la pyramide.

Ils auront peut-être un lit superposé entre deux niveaux. Nous pouvons compléter le tableau précédent comme suit :

Pyramide

Test

Question à laquelle on répond

Exemple

Au milieu ou au sommet selon le cas

Tests d’acceptation 

Comment vérifier une exigence métier de manière automatisée ?

Un test qui décrit les exigences du métier, et non les composants. L’implémentation peut varier.

Mais comment décider où et quand nous avons réellement besoin de tests d’acceptation ?

Voici comment je vous recommande de prendre votre décision :

  1. Demandez-vous si le comportement métier est déjà couvert par un test fonctionnel de bout en bout, qui utilisera les méthodes et classes dont vous aurez besoin pour livrer votre test d’acceptation.

  2. Si la réponse est non, vous aurez peut-être besoin d’en écrire un.

Après cela, écrivez tous vos tests d’acceptation métier le plus possible avec des tests d'intégration système. L'expérience semble indiquer que c'est le niveau le plus équilibré en général pour les tests d'acceptation. Assurez-vous que vos tests d’acceptation peuvent être exécutés ensemble. Utilisez @Tag, par exemple !

Voici un exemple pour une application web : « Les utilisateurs authentifiés doivent pouvoir supprimer leurs profils pour se désinscrire de notre site ». Cela implique de tester qu’un utilisateur peut s'authentifier et utiliser l’application pour se désinscrire. Ensuite, nous devons vérifier qu’ils ne sont plus des utilisateurs inscrits. Cela ne teste pas directement un composant, mais plutôt nos attentes métiers. Les tests d’acceptation sont écrits en français sous forme de scénario de test, mais pour les automatiser, vous allez les implémenter en utilisant les types de tests automatiques que vous avez déjà vus.

Qu’y a-t-il au-delà du sommet de la pyramide ?

Si vous sortiez votre télescope pour regarder au-dessus du sommet de votre pyramide, vous seriez aveuglés par le chaos du monde réel. Pour la majeure partie, la pyramide teste des scénarios prévisibles. Quand vous arrivez au sommet, ce n’est que là que vous savez réellement comment votre produit se comporte. Heureusement, vous aurez beaucoup d’assurance au moment où vous atteindrez ce point.

Cela ne veut pas dire que vous avez fini de tester ou que vous pouvez vous arrêter là. Vous pouvez effectuer d'autres types de tests.

Alors, que pouvez-vous continuer à tester, apprendre, et percevoir dans le monde ? Regardez ces différents types de tests :

Test

Question à laquelle on répond

Exemple

Bêta

Que se passe-t-il quand je présente une version de mon application à des utilisateurs réels ?

Si je publie mon calculateur pour des élèves réels de l’école locale, est-ce qu’il est performant et utilisable ?

A/B testing

J’ai deux idées géniales pour cette interface utilisateur ou un bout de code compliqué. Laquelle devrais-je utiliser ?

Vous pourriez sortir deux versions de votre application. L’une enverrait tous les calculs à Google, et l’autre les résoudrait elle-même. Comparez laquelle est meilleure et préférée par vos utilisateurs.

Smoke testing

L’intégration entre votre application en marche (tout le code) et la plateforme sur laquelle elle fonctionne.

L’application fonctionne sur votre plateforme de production. Les tests rapides vérifient que ses configurations sont correctes et qu’elle semble gérer un ou deux bons chemins.

Pourquoi faire des tests après la sortie de votre application ? Le fait de construire une partie d’un système est votre contribution à la résolution d’un problème plus vaste. Une question que vous devez vous poser continuellement est : Quel problème est-ce que je résous ? Lorsque vous résolvez ce problème, vous devez continuer à vous demander si vous développez les bonnes choses. C’est-à-dire, est-ce que vous résolvez correctement ce problème d’une façon qui fonctionne pour vos utilisateurs et votre client dans le monde réel ?

Alors, qu’est-ce que tout cela signifie pour notre pyramide ?

Voici la pyramide finale. Elle n’a pas vraiment changé. Vous devriez simplement avoir une meilleure idée des types de tests, en particulier sur la partie supérieure. 

Pyramide de test complète
Pyramide de test complète

En parallèle de cette pyramide, il existe aussi d'autres tests, plutôt à vocation technique. En voici quelques exemples, avec un outil conseillé, que je vous laisse découvrir au-delà de ce cours :

  • les tests de performance, pour vérifier que votre application est assez rapide, avec JMeter ;

  • les tests de charge, qui s’assurent que votre application ne s’écroule pas quand de nombreuses personnes l’utilisent en même temps, avec Gatling ;

  • les tests de sécurité, qui vérifient si quelqu’un peut exploiter votre logiciel et accéder à des données qu’il ne devrait pas pouvoir atteindre, avec ZAP.

Évidemment, il existe de nombreux types de tests supplémentaires que vous pouvez effectuer. Ce que vous décidez de faire dépend de la question suivante : Sur quels éléments avez-vous besoin d’atteindre le niveau d’assurance qualité souhaité pour votre système ? En général, la plupart des bons projets devraient disposer au moins de tests unitaires, d’intégration de composants, et de bout en bout. Tout ce que vous faites au-delà de ces catégories dépend des besoins spécifiques à votre produit.

Enfin : les tests ne sont pas gratuits. Rappelez-vous que chaque test est comme un animal de compagnie. Vous devez vous engager à en prendre soin et à investir le temps nécessaire pour lui donner l’attention continue dont il aura besoin. Est-ce que votre base de code a la place d’accueillir un autre chaton ?

En résumé

  • Pour que les tests unitaires soient rapides et approfondis, ils formulent de nombreuses hypothèses, exprimées à travers les mocks.

  • Les tests d’intégration des composants valident qu’un petit nombre d’unités de code peuvent collaborer ensemble.

  • Les tests d’intégration système valident la capacité de vos unités de code à collaborer dans un système partiellement en fonction, avec des composants extérieurs simulés ou non.

  • Avec les tests de bout en bout, vous faites fonctionner le système complet et vous validez vos hypothèses.

  • Les tests d’acceptation fonctionnent de façon perpendiculaire à la pyramide et peuvent traverser les niveaux, tout en restant en principe au milieu ou en haut de la pyramide.

Maintenant que vous avez découvert un peu de théorie sur les types de tests au milieu et en haut de la pyramide, passons à la pratique... au chapitre suivant !

Exemple de certificat de réussite
Exemple de certificat de réussite