Unit & Integration Testing > Test des compossants

Références

L'actualité

Librairie

L'information

Notions de base sur le test des composants

Un composant, contrairement à toutes les autres parties d'une application Angular, combine un modèle HTML et une classe TypeScript. Le composant est vraiment le modèle et la classe travaillant ensemble. Pour tester correctement un composant, vous devez vérifier qu'il fonctionne correctement.

De tels tests nécessitent la création de l'élément hôte du composant dans le DOM du navigateur, comme le fait Angular, et l'examen de l'interaction de la classe de composant avec le DOM, comme décrit dans son modèle.

Angular TestBed facilite ce type de test, comme vous le verrez dans les sections ci-dessous. Mais dans de nombreux cas, tester la classe de composant seule, sans implication de DOM, peut valider une grande partie du comportement du composant d'une manière plus simple et plus évidente.

Test de classe de composants

Testez une classe de composants de la même manière que vous testeriez une classe de service.

Pensez à LightswitchComponent qui allume et éteint une lumière (représentée par un message à l'écran) lorsque l'utilisateur clique sur le bouton.

Vous pouvez décider uniquement de vérifier que la méthode clicked() active ou désactive l'état de la lumière et définit le message de manière appropriée.

Cette classe de composants n'a pas de dépendances. Pour tester un service sans dépendance, vous le créez avec new, piquez son API et affirmez les attentes sur son état public. Faites la même chose avec la classe de composants.

Voici le tutoriel DashboardHeroComponent.

Il apparaît dans le modèle d'un composant parent, qui lie un héros à la propriété @Input et écoute un événement généré par la propriété @Output sélectionnée.

Vous pouvez tester le fonctionnement du code de classe sans créer le composant DashboardHeroComponent ou son composant parent.

Lorsqu'un composant a des dépendances, vous pouvez utiliser le TestBed pour créer le composant et ses dépendances.

Ce qui suit WelcomeComponent dépend du UserService pour connaître le nom de l'utilisateur à saluer.

Vous pouvez commencer par créer un modèle UserService qui répond aux besoins minimaux de ce composant.

Puis fournissez et injectez le composant et le service dans la configuration TestBed.

Exercez ensuite la classe de composants en vous rappelant d'appeler les méthodes hook du cycle de vie comme Angular lors de l'exécution de l'application.


Test du composant DOM

Tester la classe de composants est aussi simple que de tester un service.

Mais un composant est plus que sa classe. Un composant interagit avec le DOM et avec d'autres composants. Les tests de classe uniquement peuvent vous renseigner sur le comportement de la classe. Ils ne peuvent pas vous dire si le composant va restituer correctement, répondre aux entrées et gestes de l'utilisateur, ou s'intégrer aux composants parent et enfant.

Aucun des tests de classe ci-dessus ne permet de répondre aux questions clés sur le comportement réel des composants à l'écran.

  • Lightswitch.clicked() est t-il lié à quoi que ce soit que l'utilisateur puisse invoquer ?
  • Est-ce que Lightswitch.message affichage ?
  • L'utilisateur peut-il réellement sélectionner le heros affiché par DashboardHeroComponent ?
  • Le nom du héros est-il affiché comme prévu (c'est-à-dire en majuscule) ?
  • Le message de bienvenue est-il affiché par le modéle de WelcomeComponent ?

Ces questions peuvent ne pas être troublantes pour les composants simples illustrés ci-dessus. Cependant, de nombreux composants ont des interactions complexes avec les éléments DOM décrits dans leurs modéles, ce qui entraîne l'apparition et la disparition de HTML lorsque le statut de ce composant change.

Pour répondre à ce type de questions, vous devez créer les éléments DOM associés aux composants, examiner le DOM pour confirmer que l'état des composants s'affiche correctement aux moments appropriés et simuler l'interaction de l'utilisateur avec l'écran pour déterminer si ces interactions font en sorte que le composant se comporte comme prévu.

Pour écrire ce type de test, vous utiliserez des fonctionnalités supplémentaires du TestBed, ainsi que d'autres aides au test.

Tests générés par la CLI

La CLI crée par défaut un fichier de test initial lorsque vous lui demandez de générer un nouveau composant.

Par exemple, la commande CLI suivante génère un BannerComponent dans le dossier app/banner (avec un modèle et des styles intégrés) :

Il génère également un fichier de test initial pour le composant banner-external.component.spec.ts, qui ressemble à ceci :


Réduire l'installation

En réalité, seules les trois dernières lignes de ce fichier testent le composant. Elles affirment simplement que Angular peut créer le composant. Le reste du fichier consiste en un code de configuration standard prévoyant des tests plus avancés qui pourraient s'avérer nécessaires si le composant évolue en quelque chose de substantiel.

Vous en apprendrez plus sur ces fonctionnalités de test avancées ci-dessous. Pour le moment, vous pouvez réduire radicalement ce fichier de test à une taille plus gérable :

Dans cet exemple, l'objet de métadonnées passé à TestBed.configureTestingModule déclare simplement le composant BannerComponent à tester.

createComponent()

Après la configuration TestBed, vous appelez sa méthode createComponent().

TestBed.createComponent() crée une instance de BannerComponent, ajoute un élément correspondant au DOM test-runner et renvoie un ComponentFixture.

ComponentFixture

Le ComponentFixture est un faisceau d'essai pour interagir avec le composant crèé et son élément correspondant.
Accédez à l'instance de composant via la fixture et confirmez qu'elle existe avec une attente Jasmine :

beforeEach()

Vous ajouterez plus de tests à mesure que ce composant évolue. Plutôt que de dupliquer la configuration TestBed de chaque test, vous effectuez un refactor pour extraire la configuration en un jasmin beforeEach() et certaines variables de support :

Ajoutez maintenant un test qui extrait l'élément du composant fixture.nativeElement et recherche le texte attendu.


nativeElement

La valeur de ComponentFixture.nativeElement a le anytype. Plus tard, vous rencontrerez le DebugElement.nativeElement et il a aussi le anytype.

Angular ne peut pas savoir au moment de la compilation de quel type d'élément (nativeElement) HTML il s'agit ou même s'il s'agit d'un élément HTML. L'application peut s'exécuter sur une plateforme autre que le navigateur, telle que le serveur ou un Web Worker, où l'élément peut avoir une API réduite ou ne pas exister du tout.

Les tests de ce guide sont conçus pour s'exécuter dans un navigateur. Ainsi, une valeur nativeElement sera toujours une HTMLElement ou une de ses classes dérivées.

Sachant qu'il s'agit d'une HTMLElement sorte de solution, vous pouvez utiliser le code HTML standard querySelector pour plonger plus profondément dans l'arborescence des éléments.

Voici un autre test qui demande à HTMLElement.querySelector d'obtenir l'élément de paragraphe et de rechercher le texte de la bannière :

DebugElement

La fixation Angular fournit l'élément du composant directement à travers le fichier fixture.nativeElement.

C'est en fait une méthode pratique, implémentée comme fixture.debugElement.nativeElement.

Il y a une bonne raison pour ce chemin détourné vers l'élément.

Les propriétés du nativeElement dépendent de l'environnement d'exécution. Vous pourriez exécuter ces tests sur une plate-forme sans navigateur qui ne possède pas de DOM ou dont l'émulation DOM ne prend pas en charge API complète HTMLElement.

Angular s'appuie sur l'abstraction DebugElement pour fonctionner en toute sécurité sur toutes les plateformes prises en charge. Au lieu de créer une arborescence d'éléments HTML, Angular crée une arborescence DebugElement qui enveloppe les éléments natifs de la plate-forme d'exécution. La propriété nativeElement décompresse DebugElement et renvoie l'objet élément spécifique à la plate-forme.

Étant donné que les exemples de tests de ce guide sont conçus pour s'exécuter uniquement dans un navigateur, les tests de nativeElement sont toujours une méthode HTMLElement dont vous pouvez explorer les méthodes et propriétés connues.

Voici le test précédent, ré-implémenté avec fixture.debugElement.nativeElement :

Le DebugElement possède d'autres méthodes et propriétés utiles dans les tests, comme vous le verrez ailleurs dans ce guide. Vous importez le DebugElement depuis bibliothèque Angular.

By.css()

Bien que les tests de ce guide s'exécutent tous dans le navigateur, certaines applications peuvent au moins être exécutées sur une plate-forme différente.

Par exemple, le composant peut d'abord apparaître sur le serveur dans le cadre d'une stratégie visant à accélérer le lancement de l'application sur des périphériques mal connectés. Le moteur de rendu côté serveur peut ne pas prendre en charge l'intégralité de l'API d'élément HTML. S'il ne prend pas en charge querySelector, le test précédent pourrait échouer.

Les méthodes DebugElement de requête des offres qui fonctionnent pour toutes les plateformes prises en charge. Ces méthodes de requête utilisent une fonction de prédicat qui est renvoyée, true lorsqu'un noeud de l'arborescence DebugElement correspond aux critères de sélection.

Vous créez un prédicat à l'aide de la classe By importée d'une bibliothèque pour la plate-forme d'exécution. Voici l'importation By pour la plate-forme de navigateur :

L'exemple suivant ré-implémente le test précédent avec DebugElement.query() et la méthode By.css du navigateur.

Quelques observations :

  • La méthode statique By.css() sélectionne des noeuds DebugElement avec un sélecteur CSS standard.
  • La requête renvoie un DebugElement pour le paragraphe.
  • Vous devez décompresser ce résultat pour obtenir l'élément de paragraphe.
  • Lorsque vous filtrez par sélecteur CSS et que vous testez uniquement les propriétés de l'élément natif d'un navigateur, l'approche By.css peut être excessive.

Il est souvent plus facile et plus clair de filtrer HTMLElement avec une méthode standard telle que querySelector() ou querySelectorAll(), comme vous le verrez dans la prochaine série de tests.