Un guide complet de Cypress, le puissant framework de test end-to-end, couvrant l'installation, l'écriture de tests, le débogage, l'intégration CI/CD et les bonnes pratiques.
Cypress : Le Guide Ultime des Tests End-to-End pour les Applications Web
Dans le paysage en évolution rapide du développement web d'aujourd'hui, assurer la qualité et la fiabilité des applications web est primordial. Le test End-to-End (E2E) joue un rôle crucial dans la vérification que tous les composants d'une application fonctionnent ensemble de manière transparente du point de vue de l'utilisateur. Cypress est apparu comme un framework de test E2E de premier plan, offrant une expérience conviviale pour les développeurs, des fonctionnalités puissantes et d'excellentes performances. Ce guide complet vous guidera à travers tout ce que vous devez savoir pour démarrer avec Cypress et tester efficacement vos applications web.
Qu'est-ce que Cypress ?
Cypress est un outil de test front-end de nouvelle génération conçu pour le web moderne. Contrairement aux frameworks de test traditionnels qui exécutent les tests dans un navigateur, Cypress fonctionne directement dans le navigateur, vous offrant un contrôle et une visibilité inégalés sur le comportement de votre application. Il est conçu pour être rapide, fiable et facile à utiliser, ce qui en fait un choix populaire auprès des développeurs et des ingénieurs QA du monde entier. Cypress est écrit en JavaScript et s'exécute dans le navigateur, ce qui le rend très performant et offre un accès inégalé aux éléments internes de l'application.
Principaux avantages de l'utilisation de Cypress
- Convivial pour les développeurs : Cypress fournit une API claire et intuitive, ce qui facilite l'écriture et le débogage des tests.
- Voyage dans le temps : Cypress prend des instantanés de l'état de votre application pendant chaque commande de test, vous permettant de remonter dans le temps et de voir exactement ce qui s'est passé à tout moment.
- Rechargements en temps réel : Cypress se recharge automatiquement lorsque vous apportez des modifications à vos tests, offrant ainsi une rétroaction instantanée.
- Attente automatique : Cypress attend automatiquement que les éléments deviennent visibles ou interactifs avant d'effectuer des actions, éliminant ainsi le besoin d'attentes explicites.
- Contrôle du réseau : Cypress vous permet de simuler des requêtes et des réponses réseau, vous permettant de simuler différents scénarios et de tester la gestion des erreurs de votre application.
- Débogabilité : Cypress fournit d'excellents outils de débogage, notamment un débogueur puissant et des messages d'erreur détaillés.
- Tests multi-navigateurs : Cypress prend en charge plusieurs navigateurs, notamment Chrome, Firefox, Edge et Electron.
- Tests sans affichage : Exécutez des tests en mode sans affichage pour une exécution plus rapide dans les environnements CI/CD.
- Assertions intégrées : Cypress fournit un ensemble riche d'assertions intégrées pour vérifier le comportement attendu de votre application.
Installation et configuration
Il est simple de démarrer avec Cypress. Voici comment l'installer :
- Prérequis : Assurez-vous que Node.js et npm (Node Package Manager) sont installés sur votre système. Vous pouvez les télécharger depuis le site web officiel de Node.js.
- Installer Cypress : Ouvrez votre terminal ou votre invite de commandes, accédez au répertoire de votre projet et exécutez la commande suivante :
- Ouvrir Cypress : Une fois l'installation terminée, vous pouvez ouvrir le Cypress Test Runner en exécutant :
npm install cypress --save-dev
npx cypress open
Cette commande lancera le Cypress Test Runner, qui fournit une interface graphique pour exécuter et déboguer vos tests.
Écrire votre premier test Cypress
Créons un test simple pour vérifier que la page d'accueil d'un site web se charge correctement. Créez un nouveau fichier nommé `example.cy.js` dans le répertoire `cypress/e2e` de votre projet.
// cypress/e2e/example.cy.js
describe('Mon Premier Test', () => {
it('Visite le Kitchen Sink', () => {
cy.visit('https://example.cypress.io')
cy.contains('type').click()
cy.url().should('include', '/commands/actions')
cy.get('.action-email')
.type('fake@email.com')
.should('have.value', 'fake@email.com')
})
})
Décomposons ce test :
- `describe()` : Définit une suite de tests, qui est un ensemble de tests connexes.
- `it()` : Définit un cas de test individuel dans la suite de tests.
- `cy.visit()` : Navigue vers l'URL spécifiée.
- `cy.contains()` : Recherche un élément contenant le texte spécifié.
- `.click()` : Clique sur l'élément sélectionné.
- `cy.url()` : Obtient l'URL actuelle de la page.
- `.should()` : Fait une assertion sur l'état de l'application.
- `cy.get()` : Sélectionne un élément à l'aide d'un sélecteur CSS.
- `.type()` : Tape du texte dans l'élément sélectionné.
- `.should('have.value', 'fake@email.com')` : Affirme que la valeur de l'élément est égale à 'fake@email.com'.
Exécutez ce test dans le Cypress Test Runner pour le voir en action. Vous devriez voir le navigateur naviguer vers le site web Cypress Kitchen Sink, cliquer sur le lien « type » et vérifier l'URL.
Commandes Cypress
Cypress fournit un large éventail de commandes pour interagir avec votre application. Voici quelques-unes des commandes les plus couramment utilisées :
- `cy.visit(url)` : Navigue vers l'URL spécifiée.
- `cy.get(selector)` : Sélectionne un élément à l'aide d'un sélecteur CSS.
- `cy.contains(content)` : Sélectionne un élément contenant le texte spécifié.
- `cy.click()` : Clique sur l'élément sélectionné.
- `cy.type(text)` : Tape du texte dans l'élément sélectionné.
- `cy.clear()` : Efface le contenu d'un élément input ou textarea.
- `cy.submit()` : Soumet un formulaire.
- `cy.check()` : Coche une case à cocher ou un bouton radio.
- `cy.uncheck()` : Décoche une case à cocher.
- `cy.select(value)` : Sélectionne une option dans une liste déroulante.
- `cy.scrollTo(position)` : Fait défiler la page jusqu'à la position spécifiée.
- `cy.trigger(event)` : Déclenche un événement DOM sur l'élément sélectionné.
- `cy.request(url, options)` : Fait une requête HTTP à l'URL spécifiée.
- `cy.intercept(route, handler)` : Intercepte les requêtes HTTP correspondant à la route spécifiée.
- `cy.wait(time)` : Attend pendant la durée spécifiée.
- `cy.reload()` : Recharge la page actuelle.
- `cy.go(direction)` : Navigue vers la page précédente ou suivante dans l'historique du navigateur.
- `cy.url()` : Obtient l'URL actuelle de la page.
- `cy.title()` : Obtient le titre de la page.
- `cy.window()` : Obtient l'objet window.
- `cy.document()` : Obtient l'objet document.
- `cy.viewport(width, height)` : Définit la taille de la fenêtre d'affichage.
Ce ne sont là que quelques-unes des nombreuses commandes disponibles dans Cypress. Reportez-vous à la documentation de Cypress pour une liste complète des commandes et de leurs options.
Assertions dans Cypress
Les assertions sont utilisées pour vérifier le comportement attendu de votre application. Cypress fournit un ensemble riche d'assertions intégrées que vous pouvez utiliser pour vérifier l'état des éléments, l'URL, le titre, etc. Les assertions sont chaînées après les commandes Cypress à l'aide de la méthode `.should()`.
Voici quelques exemples d'assertions courantes :
- `.should('be.visible')` : Affirme qu'un élément est visible.
- `.should('not.be.visible')` : Affirme qu'un élément n'est pas visible.
- `.should('be.enabled')` : Affirme qu'un élément est activé.
- `.should('be.disabled')` : Affirme qu'un élément est désactivé.
- `.should('have.text', 'texte attendu')` : Affirme qu'un élément a le texte spécifié.
- `.should('contain', 'texte attendu')` : Affirme qu'un élément contient le texte spécifié.
- `.should('have.value', 'valeur attendue')` : Affirme qu'un élément a la valeur spécifiée.
- `.should('have.class', 'classe attendue')` : Affirme qu'un élément a la classe spécifiée.
- `.should('have.attr', 'nom d'attribut', 'valeur attendue')` : Affirme qu'un élément a l'attribut et la valeur spécifiés.
- `.should('have.css', 'propriété CSS', 'valeur attendue')` : Affirme qu'un élément a la propriété CSS et la valeur spécifiées.
- `.should('have.length', longueur attendue)` : Affirme qu'un élément a la longueur spécifiée (par exemple, le nombre d'éléments dans une liste).
Vous pouvez également créer des assertions personnalisées pour répondre à vos besoins spécifiques.
Meilleures pratiques pour l'écriture de tests Cypress
Le respect des meilleures pratiques peut vous aider à écrire des tests Cypress plus maintenables, fiables et efficaces. Voici quelques recommandations :
- Écrire des tests clairs et concis : Chaque test doit se concentrer sur une fonctionnalité ou un scénario spécifique. Évitez d'écrire des tests trop complexes qui sont difficiles à comprendre et à maintenir.
- Utiliser des noms de test significatifs : Donnez à vos tests des noms descriptifs qui indiquent clairement ce qu'ils testent.
- Éviter le codage en dur des valeurs : Utiliser des variables ou des fichiers de configuration pour stocker les valeurs qui peuvent changer avec le temps.
- Utiliser des commandes personnalisées : Créer des commandes personnalisées pour encapsuler la logique réutilisable et rendre vos tests plus lisibles.
- Isoler les tests : Chaque test doit être indépendant des autres tests. Évitez de vous fier à l'état de l'application des tests précédents.
- Nettoyer après les tests : Réinitialiser l'état de l'application après chaque test pour s'assurer que les tests suivants commencent à partir d'une table rase.
- Utiliser des attributs de données : Utiliser des attributs de données (par exemple, `data-testid`) pour sélectionner des éléments dans vos tests. Les attributs de données sont moins susceptibles de changer que les classes CSS ou les ID, ce qui rend vos tests plus résistants aux modifications de l'interface utilisateur.
- Éviter les attentes explicites : Cypress attend automatiquement que les éléments deviennent visibles ou interactifs. Évitez d'utiliser des attentes explicites (par exemple, `cy.wait()`) sauf si cela est absolument nécessaire.
- Tester les flux d'utilisateurs : Se concentrer sur le test des flux d'utilisateurs plutôt que sur les composants individuels. Cela vous aidera à vous assurer que votre application fonctionne correctement du point de vue de l'utilisateur.
- Exécuter les tests régulièrement : Intégrer les tests Cypress dans votre pipeline CI/CD et les exécuter régulièrement pour détecter les bogues tôt dans le processus de développement.
Techniques avancées de Cypress
Stubbing et Mocking
Cypress vous permet de simuler des requêtes et des réponses réseau, vous permettant de simuler différents scénarios et de tester la gestion des erreurs de votre application. Ceci est particulièrement utile pour tester les fonctionnalités qui dépendent d'API ou de services externes.
Pour simuler une requête réseau, vous pouvez utiliser la commande `cy.intercept()`. Par exemple, le code ci-dessous simule une requête GET vers `/api/users` et renvoie une réponse simulée :
cy.intercept('GET', '/api/users', {
statusCode: 200,
body: [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' }
]
}).as('getUsers')
Vous pouvez ensuite attendre la requête interceptée à l'aide de `cy.wait('@getUsers')` et vérifier que votre application gère correctement la réponse simulée.
Travailler avec le stockage local et les cookies
Cypress fournit des commandes pour interagir avec le stockage local et les cookies. Vous pouvez utiliser ces commandes pour définir, obtenir et effacer le stockage local et les cookies dans vos tests.
Pour définir un élément de stockage local, vous pouvez utiliser la commande `cy.window()` pour accéder à l'objet window, puis utiliser la méthode `localStorage.setItem()`. Par exemple :
cy.window().then((win) => {
win.localStorage.setItem('myKey', 'myValue')
})
Pour obtenir un élément de stockage local, vous pouvez utiliser la commande `cy.window()` puis utiliser la méthode `localStorage.getItem()`. Par exemple :
cy.window().then((win) => {
const value = win.localStorage.getItem('myKey')
expect(value).to.equal('myValue')
})
Pour définir un cookie, vous pouvez utiliser la commande `cy.setCookie()`. Par exemple :
cy.setCookie('myCookie', 'myCookieValue')
Pour obtenir un cookie, vous pouvez utiliser la commande `cy.getCookie()`. Par exemple :
cy.getCookie('myCookie').should('have.property', 'value', 'myCookieValue')
Gestion des téléchargements de fichiers
Cypress fournit un plugin appelé `cypress-file-upload` qui simplifie les téléchargements de fichiers dans vos tests. Pour installer le plugin, exécutez la commande suivante :
npm install -D cypress-file-upload
Ensuite, ajoutez la ligne suivante à votre fichier `cypress/support/commands.js` :
import 'cypress-file-upload';
Vous pouvez ensuite utiliser la commande `cy.uploadFile()` pour télécharger un fichier. Par exemple :
cy.get('input[type="file"]').attachFile('example.txt')
Travailler avec des IFrames
Tester des IFrames peut être délicat, mais Cypress fournit un moyen d'interagir avec eux. Vous pouvez utiliser la commande `cy.frameLoaded()` pour attendre qu'un IFrame se charge, puis utiliser la commande `cy.iframe()` pour obtenir l'objet document de l'IFrame.
cy.frameLoaded('#myIframe')
cy.iframe('#myIframe').find('button').click()
Cypress et l'intégration continue/le déploiement continu (CI/CD)
L'intégration de Cypress dans votre pipeline CI/CD est essentielle pour assurer la qualité de votre application. Vous pouvez exécuter des tests Cypress en mode sans affichage dans votre environnement CI/CD. Voici comment :
- Installer Cypress : S'assurer que Cypress est installé en tant que dépendance dans votre projet.
- Configurer CI/CD : Configurer votre pipeline CI/CD pour exécuter les tests Cypress après chaque build.
- Exécuter Cypress sans affichage : Utiliser la commande `cypress run` pour exécuter les tests Cypress en mode sans affichage.
Exemple de configuration CI/CD (à l'aide de GitHub Actions) :
name: Cypress Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
cypress-run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- name: Install dependencies
run: npm install
- name: Cypress run
uses: cypress-io/github-action@v5
with:
start: npm start
wait-on: 'http://localhost:3000'
Cette configuration exécutera les tests Cypress chaque fois que du code est envoyé à la branche `main` ou qu'une demande d'extraction est créée par rapport à la branche `main`. L'action `cypress-io/github-action` simplifie le processus d'exécution des tests Cypress dans GitHub Actions.
Débogage des tests Cypress
Cypress fournit d'excellents outils de débogage pour vous aider à identifier et à résoudre les problèmes dans vos tests. Voici quelques conseils pour le débogage des tests Cypress :
- Utiliser le Cypress Test Runner : Le Cypress Test Runner fournit une interface visuelle pour exécuter et déboguer vos tests. Vous pouvez parcourir vos tests une commande à la fois, inspecter l'état de l'application et afficher des messages d'erreur détaillés.
- Utiliser la commande `cy.pause()` : La commande `cy.pause()` interrompt l'exécution de votre test et vous permet d'inspecter l'état de l'application dans les outils de développement du navigateur.
- Utiliser la commande `cy.debug()` : La commande `cy.debug()` affiche l'élément sélectionné dans la console, ce qui vous permet d'inspecter ses propriétés et ses attributs.
- Utiliser les outils de développement du navigateur : Les outils de développement du navigateur fournissent une multitude d'informations sur votre application, notamment le DOM, les requêtes réseau et les journaux de la console.
- Lire attentivement les messages d'erreur : Cypress fournit des messages d'erreur détaillés qui peuvent vous aider à identifier la cause de l'erreur. Prêter attention au message d'erreur et à la trace de la pile.
Cypress vs. Autres frameworks de test
Bien que Cypress soit un framework de test end-to-end puissant, il est essentiel de comprendre comment il se compare à d'autres options populaires. Voici un bref aperçu :
- Selenium : Selenium est un framework de test d'automatisation largement utilisé. Bien que flexible et prenant en charge plusieurs langues, il peut être complexe à configurer et à maintenir. Cypress offre une expérience plus simple et plus conviviale pour les développeurs, en particulier pour les applications basées sur JavaScript.
- Puppeteer : Puppeteer est une bibliothèque Node qui fournit une API de haut niveau pour contrôler Chrome ou Chromium sans affichage. Il est excellent pour le grattage et l'automatisation des tâches du navigateur, mais peut nécessiter plus de configuration manuelle par rapport à Cypress pour les tests end-to-end.
- Playwright : Playwright est un autre framework d'automatisation multi-navigateurs développé par Microsoft. Il partage des similitudes avec Puppeteer mais offre une prise en charge plus large des navigateurs. Cypress possède un débogueur de voyage dans le temps unique et une expérience de test plus intégrée.
Le choix du framework dépend des besoins et des exigences spécifiques de votre projet. Cypress est un excellent choix pour les applications web modernes qui nécessitent des tests end-to-end rapides, fiables et conviviaux pour les développeurs.
Exemples concrets de Cypress en action
Explorons quelques exemples concrets de la façon dont Cypress peut être utilisé pour tester différents types d'applications web :
Test d'une application de commerce électronique
Vous pouvez utiliser Cypress pour tester divers flux d'utilisateurs dans une application de commerce électronique, tels que :
- Rechercher des produits
- Ajouter des produits au panier
- Passer à la caisse et passer une commande
- Gérer les paramètres du compte
Voici un exemple de test Cypress qui vérifie qu'un utilisateur peut ajouter un produit à son panier avec succès :
it('Ajoute un produit au panier', () => {
cy.visit('/products')
cy.get('.product-card').first().find('button').click()
cy.get('.cart-count').should('have.text', '1')
})
Test d'une application de médias sociaux
Vous pouvez utiliser Cypress pour tester les interactions des utilisateurs dans une application de médias sociaux, telles que :
- Créer une nouvelle publication
- Aimer une publication
- Commenter une publication
- Suivre d'autres utilisateurs
Voici un exemple de test Cypress qui vérifie qu'un utilisateur peut créer une nouvelle publication avec succès :
it('Crée une nouvelle publication', () => {
cy.visit('/profile')
cy.get('#new-post-textarea').type('Hello, world!')
cy.get('#submit-post-button').click()
cy.get('.post').first().should('contain', 'Hello, world!')
})
Test d'une application bancaire
Pour les applications bancaires, Cypress peut être utilisé pour tester des fonctionnalités essentielles telles que :
- Se connecter en toute sécurité
- Vérifier les soldes des comptes
- Transférer des fonds
- Gérer les bénéficiaires
Un test pour vérifier un transfert de fonds pourrait ressembler à ceci (avec une simulation appropriée pour la sécurité) :
it('Transfère des fonds avec succès', () => {
cy.visit('/transfer')
cy.get('#recipient-account').type('1234567890')
cy.get('#amount').type('100')
cy.intercept('POST', '/api/transfer', { statusCode: 200, body: { success: true } }).as('transfer')
cy.get('#transfer-button').click()
cy.wait('@transfer')
cy.get('.success-message').should('be.visible')
})
Conclusion
Cypress est un framework de test end-to-end puissant et polyvalent qui peut vous aider à assurer la qualité et la fiabilité de vos applications web. Son API conviviale pour les développeurs, ses fonctionnalités puissantes et ses excellentes performances en font un choix populaire auprès des développeurs et des ingénieurs QA du monde entier. En suivant les meilleures pratiques décrites dans ce guide, vous pouvez écrire des tests Cypress efficaces qui vous aideront à détecter les bogues tôt dans le processus de développement et à fournir des logiciels de haute qualité à vos utilisateurs.
À mesure que les applications web continuent d'évoluer, l'importance des tests end-to-end ne fera qu'augmenter. Adopter Cypress et l'intégrer à votre flux de travail de développement vous permettra de créer des expériences web plus robustes, fiables et conviviales.