Comment tester vos applications Web
Dans l’industrie du logiciel, tout le monde teste ses applications d’une manière ou d’une autre. De nombreuses équipes de développeurs ont des schémas de test élaborés qui sont bien intégrés à leurs pipelines d’intégration continue, mais même ceux qui n’ont pas de tests automatiques doivent toujours trouver des moyens de vérifier que leur code fonctionne comme prévu.
Créer un site Web et cliquer dessus manuellement à l’aide d’un navigateur est une variété de tests. Bien que ce ne soit pas le plus sophistiqué, il compte toujours. Il en va de même pour déclencher cURL dans la console et envoyer une requête synthétique au point de terminaison de l’API que vous venez de créer.
Cet article discutera de la façon d’automatiser les tests manuels que nous faisons déjà avant de plonger dans différents types et méthodologies de tests.
Tests d’automatisation
Les tests manuels sont suffisants pour les petites applications, mais, lorsque ces applications se développent, leur surface testable augmente avec elles, ce qui pose deux problèmes.
Premièrement, lorsque des personnes doivent effectuer des tests chaque fois qu’une nouvelle version d’une application est terminée, des incohérences peuvent survenir. Cela est particulièrement vrai s’il existe de nombreux tests. Deuxièmement, la personne qui effectue les tests ne peut pas effectuer d’autres tâches. Avec les grandes applications, les tests peuvent prendre plusieurs jours.
La façon la plus logique de résoudre ces deux problèmes consiste à automatiser ces tâches manuelles. Deux principaux types de tests existent pour les applications Web: les tests d’interface utilisateur et les tests d’API. Deux outils peuvent les automatiser.
Tests d’interface utilisateur
Les tests d’interface utilisateur peuvent être effectués avec un outil appelé Puppeteer. Puppeteer vous permet d’automatiser un test manuel de l’interface utilisateur en utilisant JavaScript. Il est installé via NPM avec la commande suivante:
$ npm i puppeteer
Vous pouvez ensuite écrire un script qui contrôle une version sans tête de Chrome pour exécuter vos tests. Ce script pourrait ressembler à ce qui suit:
(async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://google.com', {waitUntil: 'networkidle2'}); const heading = await page.$('h1'); await browser.close(); if(!heading) console.log('No heading found!');})();
Dans ce script, nous démarrons une instance sans tête de Chrome, naviguant vers example.com , et à la recherche d’un élément h1. S’il n’existe pas, un message d’erreur est enregistré.
Tests API
Les tests API peuvent être automatisés via Postman. Postman est livré avec une interface graphique pour créer des requêtes HTTP qui peuvent être enregistrées. Ces demandes peuvent être exécutées plus tard avec un simple clic de souris.
Pour commencer, téléchargez et installez l’interface utilisateur du facteur. Les étapes suivantes sont nécessaires pour créer et enregistrer une demande:
- Cliquez sur Créer une Collection à gauche
- Entrez Ma Collection comme nom de collection
- Cliquez sur Créer
- Cliquez sur les points de suspension (…) de Ma Collection à gauche
- Sélectionnez Ajouter une Demande
- Entrez Ma Demande comme nom de demande
- Cliquez Sur Enregistrer dans Ma Collection
La requête apparaît dans la barre latérale gauche sous votre collection nouvellement créée.
Si vous le sélectionnez, vous devrez entrer example.com comme URL et ajoutez un test. Pour ajouter un test, cliquez sur Tests dans la barre d’onglets sous le champ de saisie de l’URL.
Une zone de texte dans laquelle vous pouvez écrire votre test en JavaScript apparaîtra. Voici un exemple de test:
pm.test("Status code is 200", () => { pm.response.to.have.status(200);});
Si vous cliquez sur Enregistrer dans le coin supérieur droit de l’écran et Envoyez juste après, votre demande sera envoyée. Le script de test s’exécutera ensuite pour déterminer si la réponse avait ou non le statut 200.
Types de tests
Il existe trois types de tests différents. Les comprendre vous permet de choisir le bon type de test pour les différentes parties de votre pile logicielle.
Tests unitaires
Les tests unitaires sont le type de test le plus simple. Ils vérifient l’exactitude de petites parties de votre code. Un test unitaire couvre généralement un appel à une fonction ou une façon d’utiliser une classe.
Un test unitaire est généralement le premier “utilisateur” de votre code. Certaines méthodologies de test exigent même que vous écriviez le test avant l’implémentation du code d’application réel.
Les tests unitaires peuvent être utilisés à la fois dans le développement backend et frontend. Certaines équipes de développement utilisent des tests unitaires pour vérifier la sortie DOM rendue de petites parties de leur code, comme les formulaires ou les menus. Dans le backend, les tests unitaires sont souvent utilisés pour tester le code entre le serveur HTTP et la base de données ou d’autres API.
Trois coureurs de test largement utilisés pour les tests unitaires sont:
‐ AVA -AVA est privilégié dans le développement backend car il est spécialisé dans l’exécution hautement parallèle de tests. Un tutoriel AVA peut être trouvé ici.
-PHPUnit – PHPUnit est un framework populaire pour les tests unitaires en PHP. Un tutoriel PHPUnit peut être trouvé ici.
Si un test unitaire nécessite des ressources externes, telles que des connexions réseau ou des bases de données, vous écrivez probablement un test d’intégration. Ce type de test est couvert ensuite.
Tests d’intégration
Du point de vue de l’implémentation, les tests d’intégration ressemblent à des tests unitaires. La différence est que les tests d’intégration testent plusieurs parties de la pile ensemble. Par exemple, ils peuvent tester si le client et le serveur parlent le même protocole ou, dans une architecture de microservices, si les services fonctionnent correctement ensemble.
Les contrôles qui se retrouveraient généralement dans plusieurs tests unitaires indépendants peuvent être agrégés en un seul test d’intégration qui détermine si tout fonctionne bien ensemble.
Les tests d’intégration sont utilisés à la fois dans le développement frontend et backend. Ils sont parfois utilisés pour voir si les deux parties interagissent correctement, mais ils peuvent également être utilisés pour déterminer si différents modules d’une partie fonctionnent ensemble comme prévu.
Vous pouvez utiliser les mêmes coureurs de test pour les tests d’intégration que vous avez utilisés pour les tests unitaires. Cependant, Postman, l’outil d’interface utilisateur utilisé ci-dessus pour automatiser les tests API manuels, est également livré avec un outil CLI appelé Newman qui peut être intégré à votre pipeline CI / CD.
Newman peut exécuter des collections Postman exportées, ce qui vous permet de créer des demandes et des tests avec l’interface utilisateur Postman et de les exécuter ultérieurement via CLI. Un tutoriel de Newman peut être trouvé ici.
Si un test d’intégration nécessite une interaction avec l’interface utilisateur, il s’appelle un test d’interface utilisateur adressé ensuite.
Tests d’interface utilisateur
Les tests d’interface utilisateur sont les tests les plus sophistiqués. Ils essaient d’émuler le comportement des utilisateurs de manière automatisée afin que les testeurs n’aient pas à cliquer manuellement sur chaque partie de leur application.
Les tests d’interface utilisateur aident souvent à capturer une interaction spécifique qui a conduit à une erreur pour un utilisateur. Une fois capturé, il peut être reproduit en un clic afin de corriger le bug et l’empêcher de revenir dans une nouvelle version.
Les coureurs de test Jest et AVA mentionnés précédemment peuvent être utilisés ici, mais vous aurez généralement besoin d’une bibliothèque supplémentaire pour faciliter l’interaction de l’interface utilisateur via un navigateur. Les deux principales bibliothèques actuellement utilisées pour ce processus sont:
‐ Selenium – Selenium est un framework qui permet le contrôle à distance d’un navigateur via une bibliothèque appelée WebDriver. Un tutoriel sur le sélénium peut être trouvé ici.
Il existe plus de types de tests que ceux énumérés ici. D’autres peuvent avoir des objectifs différents; par exemple, les tests de charge tentent de trouver des goulots d’étranglement de performance. Gardez à l’esprit que les tests décrits ici portent parfois des noms différents. Les trois types présentés ci-dessus sont essentiels à mettre en œuvre lors de la mise en route. Utiliser l’un d’eux est préférable à n’utiliser aucun test automatisé.
Méthodologies de test
Les méthodologies de test sont des moyens de penser aux tests. Les trois décrits ci-dessous sont les plus couramment utilisés.
Test Driven Development (TDD)
TDD est la méthodologie la plus utilisée et la plus technique. Il vous recommande d’écrire vos tests avant d’écrire le code réel que vous souhaitez tester. Puisque vous devez écrire un test pour seulement la partie du code que vous implémentez, le type de test que vous écrirez est un test unitaire.
Les tests unitaires sont plutôt granulaires, donc, avec le temps, l’utilisation de cette méthodologie entraîne l’accumulation de nombreux tests. Cette réalité, associée au fait que les praticiens TDD débutants ont tendance à écrire des tests triviaux, peut conduire à la création d’une pile de tests inutiles. Pour éviter cela, il est crucial de mettre à jour et de nettoyer les tests lorsque l’équipe s’est familiarisée avec le TDD et avec les tests en général.
Il est important d’exécuter les tests fréquemment, non seulement dans un pipeline CI/ CD, mais aussi localement sur votre machine de développement. Écrivez un test, exécutez-le, voyez-le échouer, implémentez suffisamment pour que le test passe et répétez le processus.
Pour en savoir plus, consultez la description de TDD d’Agile Alliance.
Développement piloté par les tests d’acceptation (ATDD)
ATDD est une modification du TDD qui se concentre davantage sur les analyses de rentabilisation et moins sur la mise en œuvre technique. Les types de tests utilisés dans cette méthodologie sont principalement des tests d’intégration, car, souvent, plusieurs parties du système doivent être utilisées conjointement pour résoudre un besoin métier.
Étant donné que les tests sont moins techniques, il est également conseillé d’inclure des personnes non techniquement orientées dans le processus de test. Les propriétaires de produits et les clients peuvent aider à définir les analyses de rentabilisation afin qu’un développeur puisse rédiger un test pour eux. Si le test ne peut pas être exécuté avec succès, il est clair que plus de fonctionnalités doivent être implémentées.
ATDD fonctionne à un niveau d’abstraction différent de TDD, de sorte que les deux méthodologies peuvent être utilisées ensemble.
Pour en savoir plus, consultez la description de TDD d’Agile Alliance.
Développement axé sur le comportement (BDD)
Le BDD est un mélange de TDD et d’ATDD, et son objectif est d’utiliser le meilleur des deux mondes pour rendre le système global plus stable. BDD essaie de spécifier un système avec des tests qui illustrent son utilisation.
Comme ATDD, BDD tente de capturer des analyses de rentabilisation. Cependant, cela vous oblige également à remettre en question ces cas d’utilisation avec les “5 pourquoi” car les “pourquoi” sont une partie manquante dans ATDD. Bien sûr, il est préférable de demander aux clients ce qu’ils veulent au lieu de se fier uniquement aux commentaires des développeurs. Mais, il est également important de remettre en question les hypothèses de ces deux groupes.
BDD est également un mélange de TDD et d’ATDD au sens des niveaux d’abstraction. TDD ne teste que les petites parties de votre application et ATDD ne teste que le fonctionnement de ces parties. BDD vous oblige à appliquer cette méthodologie à l’ensemble de votre application et à ses petites parties, faisant de BDD une approche plus holistique des tests.
Pour en savoir plus, consultez la description de BDD d’Agile Alliance.
Conclusion
Bien qu’aucun test ne soit terrible, les tests manuels sont meilleurs et les tests automatisés sont les meilleurs.
Selon la taille de votre application, un test manuel peut empêcher les membres de l’équipe de développement de travailler sur d’autres projets pendant des jours, voire des semaines, ce qui coûte du temps et de l’argent à votre entreprise. De plus, la tâche monotone consistant à effectuer les mêmes interactions encore et encore peut entraîner des glissements qui se manifestent souvent par des bogues non capturés.
Les ordinateurs sont très bons pour répéter la même tâche encore et encore, c’est donc une bonne idée de déléguer les tests à un script et de libérer le temps de vos développeurs. Si ces tests sont intégrés dans votre pipeline CI / CD, les tests déjà écrits peuvent simplement s’exécuter implicitement lorsqu’un nouveau commit atterrit dans vos dépôts.
C’est une bonne idée d’utiliser une méthodologie de test dès le début, car, souvent, les gros problèmes au démarrage sont “quoi” et “quand” tester. Ces méthodologies peuvent aider à clarifier un processus qui rend la rédaction de tests plus cohérente pour tous les membres de l’équipe.
Leave a Reply