8
minutes
Mis à jour le
7/6/2024


Share this post

Guide pratique : améliorez la qualité de vos tests web avec Angular Testing Library et Jest, pour une application Angular plus fiable.

#
Angular
#
Testing
Brice Conraux
Software Engineer

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.

Configuration d'Angular Testing Library

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.

1. Installation des dépendances

Pour commencer, nous devons installer Angular Testing Library et ses dépendances dans notre projet Angular. Exécutons les commandes suivantes dans notre terminal :

2. Configuration de Jest

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 :

Détails du fichier setup-jest.ts

Le 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.

Écrire des tests avec Angular Testing Library

Exemple de composant

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 :

Tester le composant

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.

Recherche dans l'écran rendu

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 :

  1. getBy : Utilisé pour trouver un élément de manière synchrone. Si l'élément n'est pas trouvé, une erreur est levée.
  2. queryBy : Utilisé pour trouver un élément de manière synchrone sans lever d'erreur si l'élément n'est pas trouvé. Retourne null si l'élément n'est pas trouvé.
  3. findBy : Utilisé pour trouver un élément de manière asynchrone. Il attend que l'élément apparaisse dans le DOM. Utile pour les tests impliquant des opérations asynchrones.

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 :

  • ByText : Recherche un élément par son texte visible. Utilisé pour vérifier le contenu textuel.
  • ByRole : Recherche un élément par son rôle ARIA. Utilisé pour vérifier les éléments interactifs tels que les boutons, les liens, etc.

Avantages des différentes méthodes

  • getBy : Rapide et direct pour vérifier la présence immédiate d'un élément. Idéal pour les tests synchrones.
  • queryBy : Permet de vérifier qu'un élément n'est pas présent sans déclencher d'erreur, utile pour les assertions négatives.
  • findBy : Attend que l'élément apparaisse, ce qui est utile pour les tests asynchrones impliquant des API ou des animations.
  • ByText et ByRole : Fournissent des moyens spécifiques pour cibler les éléments en fonction de leur texte ou de leur rôle, rendant les tests plus lisibles et compréhensibles.

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.

Gestion des éléments inaccessibles

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 :

  1. Améliorer l'accessibilité : Assurez-vous que tous les éléments interactifs ont des noms et des rôles accessibles. Utilisez des attributs ARIA si nécessaire pour améliorer l'accessibilité.
  2. Utiliser des requêtes avec des sélecteurs : Pour les éléments difficiles d'accès, envisagez d'utiliser des requêtes telles que getByTestId ou getByLabelText pour cibler les éléments en fonction de leurs attributs.
Exemple de gestion des éléments inaccessibles
Déclenchement d'un événement utilisateur

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.

Avantages de userEvent

Simulation 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.

Utilisation de son équivalent, fireEvent

fireEvent 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é.

Optimisation des performances des tests

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 :

  1. Tests sélectifs : Utilisez ATL pour les composants nécessitant des tests d'interaction détaillés. Pour des tests plus simples, envisagez d'utiliser les utilitaires de test intégrés à Jest.
  2. Configuration efficace : Minimisez le code de configuration dans vos tests. Réutilisez le code de configuration dans plusieurs tests lorsque cela est possible.
  3. Simulation de services : Simulez les services et les dépendances pour réduire la complexité et le temps d'exécution de vos tests.
  4. Tests parallèles : Configurez Jest pour exécuter les tests en parallèle. Cela peut réduire significativement le temps total nécessaire à l'exécution des tests.

Conclusion

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.