Logo Wedge Digital
Cypress Developer Developer Tools Dev

Cypress tips & tricks (partie 1)

Cypress tips & tricks (partie 1)
Cette série d’articles a pour but de partager une liste de trucs et astuces que nous utilisons au sein de Wedge Digital pour implémenter nos tests automatiques fonctionnels à l’aide de l’outil Cypress.

Dans cette première partie, nous allons voir quelles règles et solutions nous avons mises en place pour faciliter l’écriture de nos tests.

Attention, les exemples donnés ici peuvent inclure des spécificités propres au framework Vue.js (mais vous devriez trouver facilement l’équivalent pour le framework que vous utilisez).

Faciliter l’écriture des tests

Complétion de code

IntelliSense peut être utilisé avec Cypress, offrant ainsi au développeur des suggestions appropriées de complétion de code.
Pour le rendre opérationnel, il suffit d’insérer la ligne suivante dans plugins/index.js :

/// <reference types="Cypress" />

Identification rapide d’un élément du DOM

Pour facilement identifier un élément du DOM en lui donnant un nom qui a du sens et qui permette de rapidement comprendre de quel type d’élément il s’agit, on insère un attribut nommé “data-cy” à cet élément, auquel on affecte l’identifiant souhaité.
Par exemple, si on a besoin de cliquer sur un bouton qui permet d’annuler une action, on peut écrire :


Dans le scénario de test on accède alors à cet élément :


Cette façon de faire permet de rendre le test résilient au changement de comportement ou au changement de style d’un élément.

Néanmoins, il arrive que l’on ait sur la même page plusieurs éléments de même type et pour lesquels il va falloir leur trouver un identifiant unique à chacun.
Pour cela, on peut rendre dynamique l’identifiant spécifié dans l’attribut data-cy en ajoutant une partie variable (exemple ci-après avec une variable index):


Ce qui donnera des identifiants comme “cancel-button-1”, “cancel-button-2”, etc.

Exécution d’une partie d’un scénario

Bien souvent quand on met à jour un test, on ne va modifier qu’une partie de ce test.
Pour éviter de perdre du temps à dérouler toutes les étapes du test avant et après la partie qui nous intéresse, on peut spécifier à Cypress les étapes qu’il doit jouer et celles qu’il ne doit pas jouer.

Pour jouer, on ajoute .only à la fonction (toutes les étapes imbriquées seront jouées).


Pour exclure, on ajoute .skip à la fonction (toutes les étapes imbriquées seront exclues).


Dans l’exemple ci-dessus, on différencie deux modes d’exécution :

- openMode : exécution en mode “fenêtré”, ce qu’on utilise lors de l’implémentation du test
- runMode : exécution en mode non “fenêtré”, généralement utilisé dans le process d’intégration continue

Arrêt de l’exécution d’un scénario au premier échec

Toujours dans le but de gagner du temps, on peut choisir d’arrêter l’exécution d’un scénario de test dès qu’une des vérifications échoue.
Pour cela, on se sert de la fonction afterEach() qui, comme son nom l’indique, est exécutée après chaque étape de test pour arrêter Cypress si l’état du test courant est ”failed” :

Création de fonctions réutilisables

Le fait de créer des fonctions réutilisables autant que possible a 2 avantages :

- un évident : ne pas dupliquer du code et donc gagner du temps dans l’écriture d’un scénario
- un moins évident mais tout aussi important : améliorer la lisibilité du scénario

Par exemple, on peut créer des fonctions d’assertion ou d’action sur les checkbox, dans un fichier .js spécifique :


Il suffit ensuite de faire un import de ce fichier dans le fichier contenant le scénario de test pour pouvoir utiliser ces fonctions.
On remarque ici l’importance de suivre toujours le même pattern pour l’identification d’un même type d’élément (via data-cy).

Création de parties de test réutilisables

Dans la même idée que précédemment, on peut implémenter des parties entières de test dont on sait qu’elles serviront dans différents scénarios. Bien souvent, seul ce qu’on appellera le contexte différenciera l’exécution de cette partie réutilisable dans l’un ou l’autre scénario.

Pour ce faire, il faut créer un fichier .js qui contient la partie de test à réutiliser et y définir une fonction que l’on met à disposition via l’instruction export :


Puis dans les scénarios de test qui ont besoin de cette fonction, il suffit de faire :

Utilisation de commandes personnalisées

Il est souvent utile de définir des commandes personnalisées qui serviront dans tous les tests.
Un exemple tout bête et assez simple : pour éviter de devoir taper pour chaque sélection d’un élément du DOM ayant un identifiant data-cy la commande fournie par Cypress :

cy.get(`[data-cy='cancel-button']`)

Chez Wedge, nous avons décidé de créer notre propre commande personnalisée afin de la rendre plus simple à écrire :


Le fichier idoine pour écrire ce genre de commandes est le fichier cypress/support/commands.js.

Ainsi, dans les scénarios de tests il suffit d’écrire :


Cette fonctionnalité de personnalisation des commandes sera plus développée dans les prochaines parties, notamment lorsqu’on verra comment nous avons implémenté nos propres commandes pour réaliser les mocks d’API ou encore la simulation de lever d’évènement interne.

Debug

Pour clore cette première partie, voici une petite astuce pour que la devtools s’ouvre automatiquement à chaque exécution de Cypress en mode fenêtré : il suffit d’ajouter dans le fichier plugins/index.js, l’instruction :

launchOptions.args.push(“ — auto-open-devtools-for-tabs”)


Conclusion

Ainsi se termine la première partie de cette série d’articles consacrés à l’utilisation de Cypress chez Wedge Digital. Si vous connaissez d’autres trucs & astuces qui facilitent l’écriture de vos tests Cypress, n’hésitez pas à les partager en commentaire !

Au menu de la prochaine partie : mocks d’API personnalisés, vérification des données envoyées aux APIs, simulation d’évènement interne, gestion du local storage, test d’un chargement de fichier, …