Plongeons dans Cypress pour des tests de bout en bout
Publié: 2022-03-10Cet article a été parrainé par nos chers amis de LambdaTest qui rendent l'expérience de test inter-navigateurs plus fluide pour tant de personnes dans le monde. Merci!
Le développement de logiciels sans tests automatisés est difficile à imaginer aujourd'hui. Une bonne variété de procédures de test différentes assurera un haut niveau de qualité. Comme base pour les tests, nous pouvons utiliser un certain nombre de tests unitaires. En plus de cela, au milieu de la pyramide, pour ainsi dire, se trouvent les tests d'intégration. Les tests de bout en bout sont tout en haut, couvrant les cas d'utilisation les plus critiques. Ce troisième type de test fera l'objet de cet article.
Cependant, les tests de bout en bout présentent certains pièges qui sont préoccupants :
- Les tests de bout en bout sont lents et constituent donc un obstacle important dans toute stratégie d'intégration et de déploiement continus (CI/CD). Non seulement cela, mais imaginez terminer une tâche, une fonctionnalité ou toute autre implémentation - attendre que le test s'exécute peut épuiser la patience de tout le monde.
- De tels tests de bout en bout sont difficiles à maintenir, sujets aux erreurs et coûteux à tous égards en raison de l'effort de débogage. Divers facteurs peuvent en être la cause. Votre test doit ressembler à un assistant, jamais à un obstacle.
- Le plus grand cauchemar pour les développeurs est un test floconneux, qui est un test exécuté de la même manière mais qui conduit à des résultats différents. C'est comme un "Heisenbug", qui ne se produit que si vous ne mesurez pas l'application testée, c'est-à-dire si vous ne la regardez pas.
Mais ne vous inquiétez pas : vous n'avez pas à succomber à ces pièges. Voyons comment prévenir bon nombre d'entre eux . Cependant, je ne me contenterai pas de promettre la lune et de ne pas livrer. Dans ce guide, nous allons écrire ensemble quelques tests, que j'ai rendus publics pour vous dans un référentiel GitHub. De cette façon, j'espère vous montrer que les tests de bout en bout peuvent être amusants ! Commençons.
Que sont les tests de bout en bout ?
Lorsque je parle de test de bout en bout (ou E2E), j'aime le qualifier de "basé sur le flux de travail". L'expression résume bien les tests de bout en bout : il simule les flux de travail réels des utilisateurs et doit inclure autant de domaines fonctionnels et de parties de la pile technologique utilisée dans l'application que possible. Au final, l'ordinateur se fait passer pour un client et essaie de se comporter comme un véritable utilisateur. Ces tests sont les meilleurs pour appliquer une contrainte constante à l'ensemble du système de votre application et, par conséquent, constituent une excellente mesure pour garantir la qualité lorsque toute la pile d'applications est présente.
Rappelons-nous ce que nous voulons réaliser avec tout cela. Nous savons que les tests frontaux sont un ensemble de pratiques permettant de tester l'interface utilisateur d'une application Web, y compris ses fonctionnalités. Logique - avec ces mesures, nous pouvons nous assurer que notre application fonctionne correctement et qu'aucune modification future ne cassera notre code. Afin d'y parvenir efficacement, vous vous demandez peut-être quoi et combien vous devez tester.
C'est une question valide. Vous pourriez trouver une réponse possible dans une métaphore : la pyramide d'automatisation des tests, introduite pour la première fois par Mike Cohn et précisée par Martin Fowler, montre comment rendre les tests efficaces . Nous trouvons des tests unitaires rapides et bon marché au niveau le plus bas de la pyramide, et des tests d'interface utilisateur longs et coûteux (tests de bout en bout) au sommet.
Expliquer cela et ses avantages et inconvénients suffirait pour son propre article. J'aimerais me concentrer sur un niveau. Les tests de bout en bout, en particulier, peuvent apporter des améliorations significatives de la qualité s'ils sont hiérarchisés efficacement. Ce faisant, nous pouvons constamment mettre notre système sous tension et nous assurer que les principales fonctions de notre application fonctionnent correctement.
Mon voyage au cyprès
Lorsque j'ai commencé à apprendre à écrire des tests de bout en bout, j'ai utilisé Mink, une bibliothèque PHP, en plus de Behat, un cadre de développement basé sur des scénarios et basé sur le comportement (BDD). J'ai commencé à utiliser Selenium, avec tous ses avantages et ses inconvénients. Parce que mon équipe avait beaucoup commencé à travailler avec Vue.js, nous sommes passés à un framework de test basé sur JavaScript pour assurer une intégration et une compatibilité sans faille. Notre choix à l'époque était Nightwatch.js, j'ai donc construit notre nouvelle suite de tests à partir de zéro.
Pendant ce temps, nous sommes souvent tombés sur des problèmes de compatibilité . Vous pourriez appeler cela l'enfer des dépendances - sans parler de toutes les limitations que nous avons vues avec Selenium et plus tard avec WebDriver.
- Dans notre équipe, nous n'avons pas pu identifier la version Chrome de notre CI. Donc, si des mises à jour de Chrome étaient publiées, Nightwatch.js n'était pas assez rapide pour être compatible, ce qui provoquait de nombreux échecs dans nos pipelines de test.
- Le nombre de causes liées aux tests de tests floconneux a commencé à augmenter, car les possibilités d'attente de Nightwatch.js ne correspondaient pas de manière optimale à notre produit.
Nous en sommes donc venus à envisager de recréer notre suite de tests. Après avoir visité une non-conférence, j'ai découvert Cypress.
Cypress est un framework de test tout-en-un qui n'utilise ni Selenium ni WebDriver. L'outil utilise Node.js pour démarrer un navigateur sous contrôle spécial. Les tests de ce cadre sont exécutés au niveau du navigateur, pas seulement au niveau du contrôle à distance. Cela offre plusieurs avantages.
Bref, voici les raisons pour lesquelles j'ai choisi ce framework :
- Excellente capacité de débogage
Le testeur de Cypress peut revenir à n'importe quel état de l'application via des instantanés. Ainsi, nous pouvons voir directement une erreur et toutes les étapes qui la précèdent. De plus, il y a un accès complet aux outils de développement de Chrome (DevTools) et les clics sont entièrement enregistrés. - Meilleures façons d'attendre les actions dans le test ou l'interface utilisateur ou dans les réponses de l'API
Cypress apporte une attente implicite, il n'y a donc pas besoin de contrôles appropriés. Vous pouvez également faire en sorte que le test attende des animations et des réponses d'API. - Les tests sont écrits en JavaScript
Cela atténue la courbe d'apprentissage pour écrire des tests. Le test runner de Cypress est open-source, il correspond donc à notre stratégie produit.
Cependant, cet article est un guide, alors arrêtons-nous avec ces informations générales et allons-y.
Commencer
Installer et démarrer Cypress
Commençons à zéro. Dans mes discussions sur Cypress, je commence généralement par créer un nouveau répertoire via mkdir
, puis j'installe immédiatement Cypress. La manière la plus simple d'installer est illustrée dans ce dessin :
Un petit indice : si vous ne souhaitez pas utiliser npm, vous pouvez installer Cypress via Yarn :
yarn add cypress --dev
Une alternative est le téléchargement direct, en utilisant les dossiers ZIP fournis par Cypress. C'est ça! Une fois l'installation terminée, vous êtes prêt à commencer.
Il existe deux façons de commencer à exécuter des tests Cypress. La première consiste à démarrer Cypress dans la console et à exécuter vos tests sans tête :
./node_modules/.bin/cypress run
La deuxième façon consiste à utiliser l'une des fonctionnalités intéressantes de Cypress, qui est son testeur intégré. Le test runner est une interface utilisateur pour exécuter des tests. Pour le lancer, vous pouvez utiliser une commande similaire :
./node_modules/.bin/cypress open
Cette commande ouvrira le lanceur de test. Lorsque vous ouvrez Cypress pour la première fois, vous verrez cette interface :
Cypress fournit des exemples de tests pré-écrits pour présenter ses fonctionnalités et vous donner quelques points de départ - c'est la raison pour laquelle les tests sont disponibles. Ignorons-les pour l'instant, car nous voulons bientôt écrire les nôtres. Cependant, veuillez garder à l'esprit cette zone "Tests d'intégration", car elle représentera une grande partie de la magie qui se produira plus tard.
Première impression de la structure de Cypress
Il est maintenant temps d'ouvrir notre projet nouvellement créé dans l'environnement de développement intégré (IDE) de votre choix. Si vous accédez à ce dossier, vous verrez la structure de test suivante :
smashing-example └── cypress └── fixtures └── integration └── plugins └── support └── cypress.json
Passons en revue ces dossiers :
-
fixtures
C'est ici que vous trouverez des données de test fixes, qui n'ont aucun rapport avec les autres entités. Ainsi, aucun ID n'est stocké ici, ce qui peut changer en fonction de l'état local. -
integration
Vous trouverez les tests réels ici. -
plugins
Ici, vous pouvez étendre Cypress, que ce soit avec des plugins Cypress existants ou les vôtres. -
support
Ici, vous pouvez étendre Cypress lui-même. Vos propres commandes et assistants se trouvent ici. -
cypress.json
Modifiez les configurations ici, y compris pour l'environnement.
Très bien, je pense que nous pouvons trouver notre chemin dans Cypress maintenant, que ce soit le testeur ou le code source. Mais par où commencer ? Que veut-on tester ?
Choisissez un cas de test
Un test typique de bout en bout peut devenir complexe, en particulier s'il comporte de nombreuses étapes. L'exécution manuelle prendrait beaucoup de temps. En raison de cette complexité, les tests E2E peuvent être difficiles à automatiser et lents à exécuter. Par conséquent, nous devons choisir avec soin les cas à automatiser.
À mon avis, le terme « basé sur le workflow » est essentiel : nous sélectionnerions des cas de test basés sur des histoires d'utilisateurs typiques. Cependant, en raison des durées d'exécution, il n'est pas conseillé de couvrir chaque flux de travail disponible. Par conséquent, nous avons besoin d'un moyen de hiérarchiser nos cas de test.
Dans mon équipe, nous avions plusieurs critères pour notre projet. Le cas de test doit :
- couvrir les flux de travail les plus généraux et les plus utilisés d'une fonctionnalité, comme les opérations CRUD (le terme "chemin heureux" décrit assez bien ces flux de travail) ;
- utiliser l'analyse des risques, couvrant les flux de travail avec des tests E2E qui sont les plus vulnérables (c'est-à-dire où les erreurs causeraient le plus de dégâts) ;
- éviter la couverture en double ;
- pas nécessairement être utilisé si les tests unitaires sont plus appropriés (utilisez un test E2E pour tester la réponse de votre logiciel à une erreur, pas l'erreur elle-même).
La deuxième chose la plus importante à garder à l'esprit est de ne tester que le flux de travail que vous souhaitez explicitement tester. Toutes les autres étapes requises pour que votre test fonctionne doivent être effectuées avec des opérations d'API en dehors du test, pour éviter de les tester. De cette façon, vous garantirez des durées d'exécution de test minimales et obtiendrez un résultat clair de votre cas de test en cas d'échec. Considérez ce flux de travail comme le ferait un utilisateur final : concentrez-vous sur l'utilisation de la fonctionnalité plutôt que sur la mise en œuvre technique .
Exemple:
Si vous souhaitez tester le processus de paiement dans une boutique en ligne, n'effectuez pas toutes les autres étapes, telles que la création des produits et des catégories, même si vous en aurez besoin pour traiter le paiement. Utilisez, par exemple, une API ou un vidage de base de données pour faire ces choses, et configurez le test uniquement pour le paiement.
Exemple : Trouver mes articles dans Smashing Magazine
Je veux écrire un test pour ce site Web, Smashing Magazine. Je ne peux pas garantir que ce test sera à jour pour toujours, mais espérons qu'il durera. Dans tous les cas, vous pourrez trouver cet exemple dans un référentiel GitHub.
Création de notre premier test Cypress
Dans le dossier d' integration
, nous allons commencer par créer un nouveau fichier. Appelons-le find-author.spec.js
. Le suffixe .spec
signifie "spécification". En termes de test, cela fait référence aux détails techniques d'une fonctionnalité ou d'une application donnée que votre application doit remplir.
Pour transformer ce fichier JavaScript vide en maison de test, nous allons commencer par donner sa structure à la suite de tests. Nous allons utiliser la méthode nommée describe
. describe()
, ou context()
, est utilisé pour contenir et organiser les tests. En d'autres termes, cette méthode sert de cadre à nos tests. Ainsi, notre fichier de test ressemblera à ceci :
// find-author.spec.js describe('Find authors at smashing', () => { //... });
L'étape suivante consiste à créer le test réel. Nous allons utiliser la méthode it
. it()
, ou specify()
, est utilisé pour représenter le test réel. Comme vous pouvez le voir, nous pouvons capturer plusieurs tests dans un seul fichier, ce qui permet d'excellentes options de structuration.
// find-author.spec.js describe('Find authors at smashing', () => { it('Find the author Ramona Schwering', () => { cy.log('This is our brand-new test'); }); });
Petit indice : Si vous connaissez Mocha, vous avez peut-être remarqué quelques similitudes. Cypress est construit sur Mocha, la syntaxe est donc la même.
Très bien, continuons. Si nous exécutons notre test dans le test runner de Cypress, nous remarquerons que Cypress ouvrira un navigateur pour exécuter le test. Ce navigateur est visible dans la capture d'écran ci-dessous :
Toutes nos félicitations! Nous avons écrit notre premier test ! Bien sûr, ça ne fait pas grand chose. Nous devons continuer. Remplissons notre test de vie.
Remplissez le test de vie
Quelle est la première chose à faire lors du test d'un site Web ? Bon, nous devons ouvrir le site Web. Nous pouvons le faire en utilisant une commande Cypress. Quelle est la commande, vous vous demandez peut-être?
Travailler avec les commandes
Il existe principalement deux types d'instructions utilisées dans un test E2E. Le premier type d'instruction, les commandes, représente les différentes étapes du test. Dans le contexte de Cypress, les commandes sont tout ce que Cypress fait pour interagir avec votre site Web. Cette interaction peut être n'importe quoi - un clic, faire défiler le site Web ou même trouver un élément. En conséquence, les commandes seront l'une des choses importantes avec lesquelles nous remplirons notre test.
Ainsi, notre première commande sera celle de naviguer vers le site Web - smashingmagazine.com
. Cette commande s'appelle visit
.
En l'utilisant, notre test ressemblera à ceci :
// find-author.spec.js describe('Find authors at smashing', () => { it('Find the author Ramona Schwering', () => { cy.visit('https://www.smashingmagazine.com/'); }); });
Il y a une commande que j'utilise souvent - et vous aussi. Ça s'appelle get
:
cy.get('selector');
Cette commande renvoie un élément en fonction de son sélecteur - similaire à $(…)
de jQuery. Donc, vous utiliseriez cette commande pour trouver les pièces avec lesquelles interagir. Habituellement, vous l'utiliseriez pour démarrer une chaîne de commandes. Mais attendez - qu'entend-on par une chaîne de commandements ?
Comme mentionné au début de cet article, tous les tests et tout ce qui va avec sont écrits en JavaScript. Vous pouvez placer les commandes dans les tests (c'est-à-dire les instructions) dans une chaîne (chaînée, en d'autres termes). Cela signifie que les commandes peuvent transmettre un sujet (ou une valeur de retour) d'une commande à la commande suivante, comme nous le savons de nombreux frameworks de test.
Très bien, nous allons commencer une chaîne de commandes avec la commande get
. Pour trouver un élément avec get
, nous devons d'abord trouver son sélecteur. Trouver un sélecteur unique est essentiel, car Cypress renverrait autrement tous les éléments correspondants ; alors, gardez cela à l'esprit et évitez-le si ce n'est pas intentionnel.
Interagir avec les éléments
Cypress lui-même a une fonctionnalité pour vous aider à trouver les sélecteurs des éléments avec lesquels vous souhaitez travailler. Cette fonctionnalité s'appelle le terrain de jeu du sélecteur et vous aide à découvrir les sélecteurs uniques d'un composant ou à voir tous les éléments correspondants pour un sélecteur ou une chaîne de texte. Ainsi, cette fonctionnalité peut vous aider beaucoup dans cette tâche. Pour l'activer, cliquez simplement sur l'icône en forme de croix dans l'en-tête de l'interface utilisateur de votre test, puis survolez l'élément souhaité :
Comme on le voit dans la capture d'écran ci-dessus, une info-bulle affichera le sélecteur au survol ou dans cette petite barre sous l'icône en forme de croix, qui est apparue lorsque l'élément a été cliqué. Dans cette barre, vous pouvez également voir combien d'éléments correspondraient au sélecteur donné, ce qui garantit son caractère unique dans notre cas.
Parfois, ces sélecteurs générés automatiquement peuvent ne pas être ceux que vous souhaitez utiliser (par exemple, s'ils sont longs ou difficiles à lire ou ne remplissent pas vos autres critères). Le sélecteur généré ci-dessous est difficile à comprendre et trop long, à mon humble avis :
Dans ce cas, je reviendrais aux DevTools du navigateur pour trouver mes sélecteurs uniques. Vous connaissez peut-être ces outils ; dans mon cas, je choisis souvent Chrome à cet effet. Cependant, d'autres navigateurs pris en charge peuvent fournir des fonctionnalités similaires. Le processus ressemble à celui de Selector Playground, sauf que nous utilisons les fonctionnalités de DevTools dans l'onglet « Élément ».
Pour vous assurer qu'un sélecteur est unique, je vous recommande de le rechercher dans la vue de code de votre DevTools. Si vous ne trouvez qu'un seul résultat, vous pouvez être sûr qu'il est unique.
Saviez-vous qu'il existe de nombreux types de sélecteurs différents ? Selon la variété, les tests peuvent avoir une apparence et même se comporter assez différemment. Certaines variétés sont mieux adaptées aux tests de bout en bout que d'autres. Si vous voulez savoir quels sélecteurs utiliser pour garder vos tests stables et propres, je peux vous indiquer l'un de mes articles qui couvre ce problème. Les développeurs de Cypress fournissent eux-mêmes des conseils sur ce sujet dans leurs meilleures pratiques.
Notre test sous forme de séquence de commandes
Bon, revenons à notre test. Dans celui-ci, nous voulons afficher notre flux de travail :
"En tant qu'utilisateur, je rechercherai l'article de l'auteur et naviguerai sur le site Web de l'auteur via la zone de référence dans l'un de ses articles."
Nous reproduirons les étapes qu'un utilisateur suivrait en utilisant des commandes. Je vais coller ci-dessous le test terminé avec des commentaires, qui expliqueront les étapes :
// find-author.spec.js it('Find the author Ramona Schwering', () => { // Open the website cy.visit('https://www.smashingmagazine.com'); // Enter author's name in search field cy.get('#js-search-input').type('Ramona Schwering'); // Navigate to author's article cy.get('h2 > a').first().click(); // Open the author's page cy.get('.author-post__author-title').click(); });
Cet exemple traite du workflow que nous souhaitons tester. Cypress exécutera ce test. Alors, est-il temps de dire « Félicitations » ? Avons-nous enfin fini d'écrire notre premier test ?
Eh bien, s'il vous plaît, regardez de plus près . Cypress l'exécutera, mais il ne fera que ce que le test lui dit, c'est-à-dire tout ce que vous avez écrit. Si vous l'exécutez dans le testeur, vous pouvez voir s'il a réussi, mais pas au cas où vous l'exécuteriez sans tête. Avec ce test, nous savons seulement si Cypress a pu exécuter nos commandes avec succès, pas si nous nous sommes retrouvés sur le site Web de l'auteur. Nous devons donc enseigner notre test pour le déterminer.
Travailler avec des assertions
Le deuxième type d'instruction s'occupe des descriptions de l'état souhaité de l'interface utilisateur, c'est-à-dire si quelque chose doit exister, être visible ou ne plus être visible. Les assertions dans Cypress sont basées sur les assertions Chai et Sinon-Chai, ce qui est perceptible dans la syntaxe.
N'oubliez pas que nous voulons vérifier si nous sommes sur la page de profil de l'auteur - la mienne dans cet exemple. Donc, nous devons ajouter une assertion pour exactement cela:
// find-author.spec.js it('Find the author Ramona Schwering', () => { // Open the website cy.visit('https://www.smashingmagazine.com'); // Enter author's name in search field cy.get('#js-search-input').type('Ramona Schwering'); // Navigate to author's article cy.get('h2 > a').first().click(); // Open the author's page cy.get('.author-post__author-title').click(); // Check if we're on the author's site cy.contains('.author__title', 'Ramona Schwering').should('be.visible'); });
Très bien, maintenant nous avons écrit un test qui a de la valeur. Alors, oui, félicitations pour avoir écrit votre premier test… même s'il n'est pas encore parfait.
Rendons notre test joli
Même si nous avons réussi à écrire un premier test significatif et appris le concept de base dans le processus, je ne fusionnerais pas encore celui-ci s'il était proposé dans une pull request. Il reste quelques choses à faire pour le faire briller.
Prends ton temps
Cypress a une option de nouvelle tentative intégrée dans presque toutes les commandes, vous n'avez donc pas à attendre pour voir si, par exemple, un élément existe déjà. Cependant, cela ne regarde que si un élément existe dans le DOM, pas plus que cela. Cypress ne peut pas prédire tout ce que fait votre application, il peut donc y avoir des irrégularités si vous vous fiez uniquement à cela.
Que ferait un utilisateur s'il voulait voir un site Web qui est toujours en cours de chargement ? Ils attendraient très probablement que certaines parties du site Web deviennent visibles (donc chargées) et interagiraient ensuite avec elles. Dans notre test, nous voulons imiter précisément cela : nous voulons attendre les changements dans l'interface utilisateur avant de commencer à interagir . Dans la plupart des cas, nous limiterions ce comportement aux éléments dont nous avons besoin, utilisant ainsi des assertions sur ces éléments.
Comme vous pouvez le voir, nous devons faire attendre notre test à plusieurs reprises. Cependant, attendre trop de fois n'est pas bon non plus. En règle générale, je suggérerais d'utiliser une assertion pour vérifier si l'élément avec lequel interagir a été entièrement chargé, comme première étape pour déterminer si le site Web testé a été chargé.
Examinons une telle partie de notre test à titre d'exemple. J'ai ajouté une assertion pour m'assurer que notre page est entièrement chargée :
// find-author-assertions.spec.js // Open website cy.visit('https://www.smashingmagazine.com'); // Ensure site is fully loaded cy.get('.headline-content').should('be.visible'); // Enter author's name in the search field cy.get('#js-search-input').type('Ramona Schwering');
Continuez à ajouter des assertions de cette manière à tous les cas où notre site Web aura des temps de chargement ou plusieurs éléments qui doivent être rendus à nouveau. Pour le fichier de test complet, veuillez consulter le test correspondant dans le référentiel GitHub.
Pour éviter de tomber dans le piège des tests floconneux, je voudrais vous donner un dernier indice : n'utilisez jamais de temps d'attente fixes, tels que cy.wait(500)
ou similaire.
Les réponses API sont vos amis
Il y a une possibilité d'attente intéressante en particulier que j'aime utiliser dans mes tests. Dans Cypress, il est possible de travailler avec des fonctionnalités réseau — une autre façon utile d'attendre dans votre application consiste à utiliser ces fonctionnalités pour travailler avec des requêtes réseau . De cette façon, vous pouvez faire en sorte que le test attende une réponse API réussie.
Si nous nous souvenons de notre flux de travail comme exemple, une étape pourrait tirer parti d'une possibilité d'attente d'API. Je pense à la recherche. Une user story correspondante pourrait être la suivante :
"En tant que développeur, je veux m'assurer que nos résultats de recherche sont entièrement chargés afin qu'aucun article de résultats plus anciens ne trompe notre test."
Appliquons cela à notre test. Tout d'abord, nous devons définir l'itinéraire que nous voulons attendre plus tard. Nous pouvons utiliser la commande intercept
pour cela. Je rechercherais la demande, en apportant les données dont j'ai besoin - les résultats de la recherche dans ce cas.
Pour que cet exemple reste simple, j'utiliserai un caractère générique pour l'URL. Après cela, j'utiliserai un alias pour que Cypress puisse travailler avec cette route plus tard.
// find-author-hooks.spec.js // Set the route to work with it('Find the author Ramona Schwering', () => { // Route to wait for later cy.intercept({ url: '*/indexes/smashingmagazine/*', method: 'POST' }).as('search'); // With this alias Cypress will find the request again //...
Dans Cypress, tous les itinéraires définis sont affichés au début du test. Donc, j'aimerais aussi mettre ces commandes d' intercept
au début de mon test.
Maintenant, nous pouvons utiliser cet alias de route dans les assertions. La façon la plus simple de le faire serait d'utiliser la commande d' wait
de Cypress, directement avec l'alias mentionné précédemment. Cependant, l'utilisation de cette commande seule conduirait à attendre la réponse quel que soit son résultat . Même les codes d'erreur tels que 400 ou 500 seraient considérés comme réussis, alors que votre application échouerait très probablement. Je vous recommande donc d'ajouter une autre assertion comme celle-ci :
// find-author-hooks.spec.js // Later: Assertion of the search request's status code cy.wait('@search') .its('response.statusCode').should('equal', 200);
De cette façon, nous pouvons attendre avec précision les données, les changements, etc. du logiciel, sans perdre de temps ni avoir de problèmes si l'application est fortement sollicitée. Encore une fois, vous pouvez trouver le fichier d'exemple complet dans mon référentiel GitHub.
Configuration de Cypress
J'ai omis un petit détail. Si vous regardez de plus près l'exemple de test complet, il diffère légèrement de ceux que nous avons utilisés ici dans ce guide.
// Cypress describe('Find author at smashing', () => { beforeEach(() => { // Open website cy.visit('https://www.smashingmagazine.com'); }); //...
Je n'utilise qu'une barre oblique pour ouvrir le site Web de Smashing Magazine. Comment ça marche? Eh bien, en utilisant cette commande comme ça, vous naviguerez vers la baseUrl
de nos tests. baseUrl
est une valeur de configuration qui peut être utilisée comme préfixe pour l'URL de la cy.visit()
ou cy.request()
. Entre autres valeurs, nous pouvons définir cette valeur dans le fichier cypress.json
. Pour notre test, nous allons définir la baseUrl
comme suit :
// cypress.json { "baseUrl": "https://www.smashingmagazine.com" }
Mention honorable : Hameçons
Il reste un sujet que je veux mentionner, même si notre exemple de test n'est pas adapté à son utilisation. Comme c'est courant dans d'autres frameworks de test, nous pouvons définir ce qui se passe avant et après nos tests via ce que l'on appelle des hooks de cycle de vie . Plus précisément, ceux-ci existent pour exécuter du code avant ou après un ou tous les tests :
// Cypress describe('Hooks', function() { before(() => { // Runs once before all tests }); after(() => { // Runs once after all tests }); beforeEach(() => { // Runs before each test }); afterEach(() => { // Runs after each test }); });
Nous voulons remplir notre fichier de test avec plus d'un test, nous devons donc rechercher les étapes communes que nous voulons exécuter avant ou après eux. Notre première ligne en est un bon exemple, étant la commande visit
. En supposant que nous voulions ouvrir ce site Web avant chacun de ces tests, un hook beforeEach
dans notre exemple ressemblerait à ceci :
// Cypress describe('Find author at smashing', () => { beforeEach(() => { // Open website cy.visit('https://www.smashingmagazine.com'); }); //...
Je l'utilise fréquemment dans mon travail quotidien pour m'assurer, par exemple, que mon application est réinitialisée à son état par défaut avant le test , isolant ainsi le test des autres tests. ( Ne vous fiez jamais aux tests précédents ! ) Exécutez vos tests isolément les uns des autres pour garder le contrôle sur l'état de l'application.
Chaque test doit pouvoir s'exécuter seul, indépendamment des autres tests. Ceci est essentiel pour garantir des résultats de test valides . Pour plus de détails à ce sujet, consultez la section "Données que nous avions l'habitude de partager" dans l'un de mes articles récents. Pour l'instant, référez-vous à l'exemple complet sur GitHub si vous souhaitez voir l'intégralité du test.
Conclusion
À mon avis, les tests de bout en bout sont une composante essentielle de CI, maintenant la qualité des applications à un niveau élevé et en même temps soulageant le travail des testeurs. Cypress est mon outil de choix pour déboguer des tests de bout en bout rapidement, de manière stable et efficace, et pour les exécuter parallèlement à toute demande d'extraction dans le cadre de CI. La courbe d'apprentissage est douce si vous êtes déjà familiarisé avec JavaScript.
J'espère avoir pu vous guider un peu et vous avoir donné un point de départ pour écrire des tests Cypress et quelques conseils pratiques pour commencer. Bien sûr, tous les exemples de code sont disponibles dans le référentiel GitHub, alors n'hésitez pas à y jeter un œil.
Bien sûr, ce n'est qu'un point de départ ; il y a beaucoup plus de choses à apprendre et à discuter concernant les tests Cypress — je vais vous laisser quelques suggestions sur ce qu'il faut apprendre ensuite. Dans cet esprit, bon test !
Ressources
- Exemple de fracas original, Ramona Schwering
Référentiel GitHub pour l'exemple de cet article. - Documentation Cyprès
- "Recettes", Cyprès
Une sélection d'exemples, de recettes et de cours. - "Apprendre à coder avec JavaScript : Cypress" (leçon), CodeLikeThis
- Meilleures pratiques pour l'écriture de tests de bout en bout », Shopware Docs