Chez Sipios, nous croyons que l’optimisation des tests des applications web est essentielle pour garantir la qualité et la fiabilité de notre code.
Les tests permettent de vérifier que chaque composant de votre application fonctionne comme prévu, répond correctement aux interactions des utilisateurs et reste robuste face aux modifications futures. De plus, des tests bien écrits peuvent servir de documentation, fournissant des indications sur le comportement attendu de l'application. Pour les développeurs utilisant Angular avec Jest, l'intégration d'Angular Testing Library (ATL) peut considérablement simplifier et améliorer le processus de test. Cette bibliothèque offre des outils et des méthodes plus intuitifs pour écrire des tests qui simulent les interactions réelles des utilisateurs.
Cet article vous guidera à travers la mise en œuvre d'Angular Testing Library dans un projet Angular existant utilisant Jest. Nous explorerons les fonctionnalités clés d'ATL, notamment render, screen, userEvent et fireEvent, et comment elles peuvent rendre nos tests plus simples et plus efficaces.
Cet article suppose que vous avez déjà un projet Angular existant que vous souhaitez tester avec Jest installé. Pour ceux qui commencent tout juste, je recommande de suivre le tutoriel officiel Angular Tour of Heroes. Ce tutoriel offre une excellente introduction à Angular et vous aidera à créer une application où vous pourrez ensuite appliquer les concepts abordés dans cet article.
Pour commencer, nous devons installer Angular Testing Library et ses dépendances dans notre projet Angular. Exécutons les commandes suivantes dans notre terminal :
Ensuite, assurons-nous que Jest est correctement configuré dans notre projet. Nous devrions avoir un fichier jest.config.js à la racine de notre projet. Voici un exemple de configuration pour un projet Angular :
setup-jest.tsLe fichier setup-jest.ts est utilisé pour ajouter des configurations spécifiques à Jest avant l'exécution des tests. Dans ce cas, nous ajoutons des matchers supplémentaires fournis par Jest DOM pour faciliter les assertions sur le DOM.
Pour illustrer l'utilisation de l'Angular Testing Library, nous allons utiliser un composant du tutoriel officiel Angular Tour of Heroes. Prenons comme exemple le HeroDetailComponent :
Angular Testing Library nous permet de rendre dynamiquement le composant que nous voulons tester et d'interagir avec lui. Il existe une fonction dédiée pour configurer le composant et personnaliser ses propriétés, imports et services injectés : render
Ici, nous utilisons un composant basique, ce qui rend l'utilisation de render simple. Cependant, render peut également être utilisé pour des composants plus complexes et permet une configuration similaire à celle de TestBed, couramment utilisé. Pour voir toute la puissance de cette fonction, je vous recommande de consulter la documentation d'Angular Testing Library.
Avertissement : Veuillez noter que get, query, find et byRole, byText ne sont pas des méthodes en elles-mêmes. Dans la partie suivante, nous parlerons de ces différentes parties séparément afin de comprendre leur utilisation. Cependant, elles doivent toujours être associées ensemble pour une utilisation correcte. Par exemple, utiliser getByText, queryByRole ou findByText sont des combinaisons fonctionnelles.
Angular Testing Library fournit plusieurs méthodes pour rechercher des éléments rendus à l'écran. Les principales méthodes sont get, find, et query, chacune avec des variantes comme ByText et ByRole. Voici comment les utiliser et les différences entre elles :
null si l'élément n'est pas trouvé.Dans tous les cas, ces méthodes lèvent une erreur si plusieurs éléments correspondants sont trouvés. Cependant, elles ont toutes des variantes (getAllBy, queryAllBy, findAllBy).
Exemple de test avec différentes méthodes de recherche
Variantes
Il existe de nombreuses variantes à ajouter à nos trois préfixes (get, query, find) pour rechercher le DOM rendu. Voici deux des plus utiles :
Avantages des différentes méthodes
Ces méthodes de recherche rendent les tests plus intuitifs et alignés sur les interactions réelles des utilisateurs, améliorant la robustesse et la maintenabilité de vos tests.
Parfois, vous pouvez rencontrer des éléments inaccessibles via les méthodes getBy, surtout s'ils ont des noms vides ou manquent d'attributs ARIA appropriés. Voici quelques stratégies pour gérer ces situations :
getByTestId ou getByLabelText pour cibler les éléments en fonction de leurs attributs.Pour tester si le bouton "Save" appelle correctement la méthode save lorsqu'il est cliqué, nous utiliserons jest.spyOn pour espionner la méthode et userEvent pour simuler le clic.
Ici, nous simulons simplement un clic. Cependant, userEvent permet de tester un éventail beaucoup plus large d'interactions utilisateur. Pour une liste complète, je vous invite à consulter la documentation d'Angular Testing Library liée. Vous trouverez juste en bas une liste des quelques avantages à utiliser userEvent.
userEventSimulation réaliste des interactions utilisateur
Naturelle et complète : userEvent permet une simulation plus complète des interactions utilisateur. Par exemple, un clic de souris n'est pas seulement un événement isolé mais une série d'actions (clic, relâchement, focus, etc.). userEvent.click simule ces actions de manière réaliste, ce qui est essentiel pour tester des comportements complexes.
Délais simulés : Les actions simulées avec userEvent incluent des délais réalistes entre les événements, ce qui peut révéler des problèmes de synchronisation ou des conditions de concurrence qui pourraient ne pas être détectés autrement.
Précision et robustesse des tests
Précision accrue : Les interactions simulées avec userEvent sont plus proches des actions réelles des utilisateurs, rendant les tests plus précis et représentatifs des scénarios d'utilisation réels.
Robustesse : Les tests utilisant userEvent sont moins susceptibles de passer à côté de bugs subtils liés aux événements utilisateur. En simulant des interactions complètes, ces tests peuvent détecter des erreurs qui n'apparaissent que dans des conditions d'utilisation spécifiques.
Clarté et maintenabilité du code
Lisibilité : Les tests écrits avec userEvent sont faciles à lire et à comprendre. Les fonctions telles que userEvent.click, userEvent.type et userEvent.clear décrivent explicitement les actions de l'utilisateur, rendant les tests plus intuitifs.
Maintenabilité : La clarté et la précision des tests écrits avec userEvent améliorent la maintenabilité du code de test. Les développeurs peuvent facilement comprendre et mettre à jour les tests à mesure que les interactions utilisateur évoluent.
fireEventfireEvent est une méthode fournie par Testing Library pour déclencher des événements DOM de manière programmatique. Bien pratique pour des cas simples, fireEvent ne simule pas les interactions utilisateur avec le même réalisme que userEvent. Contrairement à userEvent, qui reproduit une séquence complète d'actions (y compris les délais naturels entre un "clic" et un "relâchement" de la souris), fireEvent déclenche uniquement l'événement ciblé sans ces détails supplémentaires. Cela peut suffire pour des tests unitaires basiques, mais pour des tests d'interaction utilisateur plus réalistes et représentatifs, userEvent est généralement préféré.
Bien que Angular Testing Library (ATL) propose des outils puissants pour les tests, elle est également relativement lourde et peut affecter les temps d'exécution de votre CI. Il est important d'utiliser ATL avec discernement pour éviter les problèmes de performances. Voici quelques conseils pour améliorer le temps d'exécution de vos tests :
Intégrer Angular Testing Library avec Jest dans un projet Angular existant peut considérablement améliorer votre flux de travail de test. Les outils et méthodes fournis par ATL sont conçus pour rendre vos tests plus simples, plus intuitifs et plus proches des interactions réelles avec les utilisateurs. En suivant les étapes et exemples décrits dans cet article, vous serez bien équipé pour écrire des tests robustes et faciles à entretenir pour vos applications Angular.