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.