Test angulaire : test de composants
Aperçu
Dans l'article précédent , j'ai défini les "tests unitaires" et comment nous pouvons appliquer ces tests à notre application angulaire. Nous convenons que, par définition, notre logique métier devrait vivre en dehors de nos composants, et la plupart de nos fonctionnalités vivront dans des canaux, des directives et des services, ce qui signifie que la plupart de nos tests unitaires testeront ces types de classes. Dans cet article, j'ai également publié l'essentiel d'un composant angulaire avec sa logique de modèle déplacée du composant vers un tube, ne laissant qu'un Input()dans la définition de classe et quelques modèles. Nous serions tous d'accord pour dire qu'à tout moment, quelqu'un pourrait entrer et ajouter ou supprimer des éléments dans l'élément, et il n'y a aucune quantité de tests unitaires qui pourraient capturer ces changements.
Ainsi, si vous ne pouvez pas utiliser les tests unitaires pour tester correctement un composant, il ne vous reste plus qu'à tester les composants, l'intégration ou de bout en bout.
Les tests d'intégration peuvent fonctionner, mais par définition, les tests d'intégration se produisent lorsque vous testez des unités individuelles et que vous les combinez pour les tester en groupe. Ainsi, par exemple, vous pouvez tester ComponentAavec ComponentB, et c'est probablement bien dans certains cas. Mais que se passe-t-il lorsque vous vous intégrez ComponentAà ComponentC? Êtes-vous à l'aise de dire que le premier test que vous avez créé est assez bon pour expédier votre produit en production ?
Selon les docs angulaires :
Les éléments de base du framework Angular sont les composants Angular…
Les composants sont conçus pour être combinés avec et consommés par différents composants pour créer votre application. Par conséquent, vous devez être en mesure de vous assurer que vous disposez d'une source de vérité pour le DOM, en particulier vos fonctionnalités Inputet Outputpropriétés d'accessibilité, et tout style que vous jugez pertinent pour vous assurer qu'il est toujours valide et que vous n'auriez pas besoin de tester manuellement.
Revenons au composant Header :
A première vue, il n'y a pas grand chose à tester . Dans un monde idéal, nous saurions que le NameDisplayPipea des tests qui valident les valeurs fournies par le composant et renvoient ce que nous attendons. Mais que se passe-t-il si quelqu'un ajuste accidentellement le h1à un h2? Que se passe-t-il si quelqu'un supprime accidentellement l'initialisation du titre ?
Les tests de composants à la rescousse
Les tests de composants sont incroyables car ils éliminent le besoin de tester manuellement de nombreuses choses que nous avons l'habitude de tester manuellement. Par exemple, je ne connais que quelques développeurs qui pensent définir la structure du template du composant (la partie la plus cruciale) à travers des tests ; cependant, je connais de nombreux AQ et concepteurs qui vérifient manuellement ces choses. Pourtant, c'est quelque chose dont on ne discute généralement pas. Nous tenons à tester nos fonctionnalités et nos comportements, mais nous ne souhaitons tester les modèles qu'une fois le code en production. C'est simplement une réflexion après coup.
Supposons que l'on me donne une maquette d'une page avec un en-tête, un corps et un pied de page. Pour les besoins de cet article, le contenu du corps n'a pas d'importance, mais en tant qu'élément de travail, je dois faire les trois choses en un seul sprint. Il y aurait donc au moins quatre composantes : a HeaderComponent, BodyComponent, FooterComponent, et a PageComponentqui intègre les trois autres…
Nous avons déjà créé le composant d'en-tête, mais supposons que ce n'est pas le cas. Si nous avons des maquettes de l'en-tête, nous pourrions définir ce qui devrait toujours être vrai dans ce composant :
- Le composant doit envelopper son contenu dans un élément d'en-tête.
- Par défaut, si un utilisateur n'est pas connecté, l'en-tête doit indiquer : "Hello, User" dans un fichier
h1. - Si un utilisateur est connecté, l'en-tête doit indiquer : "Bonjour, {{ Nom d'utilisateur }}" dans un fichier
h1.
Pour les tests de composants, vous pouvez utiliser Jasmine, Jest ou Cypress. Avec Jasmine et Jest, vous dépendez de TestBed et utilisez un appareil pour saisir des éléments et les affirmer. Avec Jest, vous ne voyez pas le modèle dans un DOM réel, il ne donne donc presque aucun avantage réel. Jasmine fonctionne très bien ici; prêt à l'emploi, il fait presque tout ce que vous voulez qu'il fasse. À savoir, pouvoir parcourir les tests dans le temps et consulter des instantanés de vos tests. En tant qu'ambassadeur Cypress, vous avez probablement deviné que je préfère utiliser Cypress pour cela, et à partir de Cypress 10.5 , nous pouvons y arriver !
TDD avec test de composants Cypress
Les tests de composants Cypress ont une syntaxe très similaire à celle des tests de bout en bout Cypress. Si vous savez comment écrire un « test Cypress », vous savez comment écrire un test de composant. En utilisant les 3 cas de test que j'ai créés ci-dessus, je peux structurer rapidement un fichier de spécifications de tests qui se rapportent à chacun d'eux :
Si vous avez vu un test Cypress dans le passé, cela devrait vous sembler assez familier. Si ce n'est pas le cas, examinons chaque pièce :
Il devrait être dans un élément d'en-tête :
it('should contain a header', () => {
cy.mount(HeaderComponent);
cy.get('header')
.should('exist')
.should('be.visible');
});
La cy.get('header')est la seule commande suivante. Nous allons utiliser javascript pour obtenir l'élément d'en-tête, puis affirmer qu'il existe non seulement mais qu'il est également visible. Ce test échouera lors de l'exécution de TDD jusqu'à ce que nous ajoutions un <header></header>élément au modèle.
Par défaut, si un utilisateur n'est pas connecté, l'en-tête doit indiquer : "Hello, User" dans un h1.
it('should have an h1 that has a greeting', () => {
cy.mount(HeaderComponent);
cy.get('h1')
.should('have.text', 'Hello, User');
});
Si un utilisateur est connecté, l'en-tête doit indiquer : "Bonjour, {{ Nom d'utilisateur }}" dans un h1.
it('should display a user name if name is provided', () => {
cy.mount(HeaderComponent, {
componentProperties: {
title: {
firstName: 'John',
lastName: 'Doe'
}
}
}); cy.get('h1')
.should('have.text', 'Hello, John Doe');
});
Facile, non ?
Sommaire
Les tests de composants sont intéressants ! Ce n'est pas un nouveau concept, mais il est plus rapide que ce à quoi nous avions accès jusqu'à la mise en œuvre de Cypress. Comme vous pouvez le voir en haut à droite de ce volet de gauche, il faut 147 ms pour exécuter ces trois tests, et chaque test prend moins de quelques minutes pour écrire si le modèle de votre composant est déjà défini. Avec ces tests comme point de départ pour ce composant d'en-tête, si quelqu'un modifie quelque chose qui n'est pas d'accord avec les trois spécifications qui existent déjà, nous savons que le composant est "cassé" et nous devons y remédier. Comme il ne s'agit que de tester l'instance de HeaderComponent, nous ne pouvons pas appeler cela un test d'intégration. Nous ne pouvons pas appeler cela un test unitaire, car aucune fonctionnalité n'est testée. Ceci, mes amis, est un test de composants !
Était-ce déjà votre compréhension des tests de composants dans Angular ? Vos tests Jasmine ou Jest sont-ils aussi propres et rapides ? Faites-moi savoir comment le vôtre contraste avec cela!
Rendez-vous au chapitre suivant, où je passerai en revue les tests d'intégration.
![Qu'est-ce qu'une liste liée, de toute façon? [Partie 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































