Testez votre site avec Cypress !

Testez votre site avec Cypress !

Vous êtes développeur et vous cherchez un outil qui vous permettra de tester votre site ?

Dans cet article, notre expert vous explique en quoi Cypress pourrait tout à fait répondre à votre besoin.

Et découvrez également comment écrire efficacement et simplement votre premier test.

Lancez-vous !

Qu'est ce que Cypress ?

Cypress est un framework permettant de réaliser des tests fonctionnels de bout à bout (end to end) de manière automatisé.

Il est utilisé principalement pour les tests d'applications web.

Les scripts de tests étant réalisés en langage Javascript, il permet aux développeurs de concevoir leurs tests rapidement et simplement,

Les tests peuvent être exécutés en temps réel. Plus précisément, le développeur peut observer les actions effectuées et ainsi constater le point de blocage. De plus, en cas d'erreur une capture d'écran et une vidéo sont mis à disposition automatiquement par Cypress, ce qui facilite le débogage.

Cypress, bien qu'assez récent, a su gagner rapidement en popularité auprès des communautés de développeurs grâce à sa facilité d'utilisation et sa capacité à écrire des tests complets rapidement.

A noter que Cypress ne repose pas sur Sélénium, ce qui facilite son installation puisqu'une seule ligne de commande suffit pour l'installer. Il est également possible de l'utiliser directement avec Docker.

Comment utiliser Cypress avec Docker ?

L'éditeur propose une image clé en main pour l'utilisation de son framework:ICI

  

Par commodité, nous déclarons conteneurs et images avec docker-compose, par exemple comme ceci :

 

 

docker-compose.yml
version: '3.2'

services:
  test-cypress:
    image: cypress/included
    container_name: test_cypress
    working_dir: /e2e
    environment:
      - CYPRESS_baseUrl=https://$\{DOMAIN}/ # domaine du site à tester.
    # command: "--record --key xxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxxx" # décommenter si vous souhaitez enregistrer sur votre dashboard cypress
    volumes:
      - ./e2e:/e2e
    extra_hosts:
      - "$\{DOMAIN}:$\{PROXY_IP}" # IP du reverse proxy s'il y'en a un. Dans notre cas nous utilisons Traefik sur nos environnements de dévelloppement.
    networks:
      - 'proxy'
networks:
  proxy:
    external: true

En mode graphique

En complément, cette configuration est ajoutée via un fichier cy-open.yml

cy-open.yml
version: '3.2'

services:
  test-cypress:
    environment:
      - DISPLAY
    entrypoint: cypress open --project /e2e
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix

Exécuter cette ligne de commande pour lancer le test

docker-compose -f ./cypress/docker-compose.yml -f ./cypress/cy-open.yml up --exit-code-from test-cypress

Attention !!! Sur linux il faut partager le serveur X afin d'exécuter une interface graphique sur le réseau. Pour cela exécuter :

xhost +local:root

En ligne de commande

En complément, cette configuration est ajoutée via un fichier cy-run.yml

cy-run.yml
version: '3.2'

services:
  test-cypress:
    command: "--browser chrome"
    # exemple pour éxécuter sur chrome et enregistrer sur le dashboard 
    #command: "--browser chrome --record --key xxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxxx"
    # exemple pour éxécuter sur firefox et enregistrer sur le dashboard 
    #command: "--browser firefox --config video=false --record --key xxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxxx"

Exécuter cette ligne de commande pour lancer le test

docker-compose -f ./cypress/docker-compose.yml -f ./cypress/cy-run.yml up --exit-code-from test-cypress

Définition du répertoire e2e/cypress

  • e2e : contient les fichiers qui seront exécutés pour les tests
  • fixtures : elles permettent de déclarer des données pouvant être utilisées dans des tests. Par exemple, il est possible de l'utiliser pour définir des identifiants de connexion
  • plugins : permet d'ajouter des fonctionnalités ou d'initialiser des comportements ou de la configuration spécifiques
  • results : lorsqu'un test est exécuté en CLI, l'output est placé dans ce répertoire et contient les résultats au format XML
  • screenshots : contient des captures d'écran de tests ayant échoués
  • screenshots : contient des captures d'écran de tests ayant échouéssupport : contient 2 fichiers :e2e.js : son rôle est de déclarer l'ensemble des autres fichiers js qui seront chargés pour chaque test. Par défaut il charge seulement le fichier commands.js ci-après. commands.js : il sert à déclarer des commandes pouvant être réutilisés pour plusieurs tests. Par exemple on peut ajouter une commande permettant de se connecter avec un compte client
  • videos : contient les vidéos des tests réalisés en CLI

Comment écrire un test ?

L'écriture d'un test est réalisée en javascript est relativement simple à partir du moment où vous êtes familiers avec ce langage.

Cypress est un framework et met à disposition tout un panel de méthodes permettant de les réaliser. La documentation disponible ici https://docs.cypress.io/ est bien conçue et riche en exemples.

Le mieux étant la pratique, voyons avec un exemple simple mais concret comment faire écrire un test permettant de vérifier que le client peut bien accéder à sa liste d'envie depuis son compte client. Pour valider cela il faut préalablement se connecter au compte client.

// fichier e2e/cypress/e2e/customer_spec.cy
describe('Customer', () => \{
  beforeEach(() => \{	// permet d'effecter ces actions avant chaque test
    cy.clearCookies();  // on efface les cookies préalablement avant chaque test

	cy.visit('/customer/account/login/');  // on va sur la page de login
    cy.get('#email').type('username');  // on insert l'identifiant dans le formulaire de connexion
    cy.get('#pass').type('password'); // on insert le mot de passe
    cy.get('#login-form').submit();  // on valide le formulaire
    cy.url().should('include', '/customer/account/');  // on peut vérifier par l'url que l'on est sur le dashboard client
    cy.get('.welcome-msg').should('contain', 'Bonjour'); // on peut vérifier par la présence d'un mot clé sur le dashboard que l'on est bien connecté.
    
  })

  it('Login and check sidebar', () => \{
    cy.get('nav').contains("Ma liste d'envie");  // on peut vérifier que lien vers la liste d'envie est bien présent dans le menu client
  })
})

On constate que la connexion à un compte client est facile à mettre en place. Toutefois en bon développeur nous n'aimons pas faire les mêmes choses plusieurs fois, il est donc préférable d'enrichir nos cas de tests d'une fonction de connexion que l'on pourra appeler à tout instant.

Cypress nous permet d'étendre "cy" en y ajoutant des méthodes, par exemple j'y ajoute "loginAsCustomer" :

// Fichier e2e/cypress/support/commands.js

Cypress.Commands.add('loginAsCustomer', (login, password) => \{
    cy.on('uncaught:exception', (e, runnable) => \{
        cy.debug('There is an uncaught exception when login')
        console.log('There is an uncaught exception when login')
        return false
    })
    cy.visit('/customer/account/login/');
    cy.get('#email').type(login);
    cy.get('#pass').type(password);
    cy.get('#login-form').submit();

    cy.url().should('include', '/customer/account/')
    cy.get('.welcome-msg').should('contain', 'Bonjour')
});

Mon test précédent devient donc :

// fichier e2e/cypress/e2e/customer_spec.cy
describe('Customer', () => \{
  beforeEach(() => \{	
    cy.clearCookies(); 
    cy.loginAsCustomer('<username>', '<password>');  
  })

  it('Login and check sidebar', () => \{
    cy.get('nav').contains("Ma liste d'envie");  
  })
})

On peut maintenant utiliser une fixture pour gérer les données de test et éviter de mettre les données de tests en dur dans le code. Dans un premier temps, on crée le fichier de données au format json.

// Fichier e2e/cypress/fixtures/customer.json
\{
  "email": "contact@thewetailers.fr",
  "password": "XXXXXXXXX"
}

Puis, on appelle ce jeu de données dans le test précédent :

// fichier e2e/cypress/e2e/customer_spec.cy
describe('Customer', () => \{
  beforeEach(() => \{	
    cy.clearCookies(); 
    cy.fixture('customer').then((customer) => \{
      cy.loginAsCustomer(customer.email, customer.password);
    }) 
  })

  it('Login and check sidebar', () => \{
    cy.get('nav').contains("Ma liste d'envie");  
  })
})

Cypress permet également de surcharger des méthodes natives,

Voici un rapide exemple permettant d'ajouter le store code dans l'URL sur un projet Magento via la méthode cy.visit(...)

// Fichier e2e/cypress/support/commands.js
Cypress.Commands.overwrite('visit', (originalFn, url, options) => \{
    originalFn("/fr"+url, options);
});

What else ?

Il est possible de définir des viewports pour tester votre application web et vérifier le comportement en mobile, tablette et desktop.

Cypress ne se limite pas au tests fonctionnels.

Il peut permettre également de faire des tests de performances, par exemple mesurer qu'une page doit pouvoir se charger en moins de 1sec

Il est également possible d'inclure d'autres librairies pour faire des tests d'accessibilités par exemple avec la libraire cypress-axe.

Les non-développeurs ne sont pas oubliés,  il existe un plugin sur Chrome permettant d'enregistrer son parcours client et de le retranscrire en JS pour le réexécuter plus tard grâce à puppeteer.

 

Conclusion

Cypress s'avère être un framework puissant tout en étant simple d'installation et d'utilisation. Un développeur montera rapidement en compétence sur celui-ci tant l'élaboration de tests est simple et rapide grâce à une communauté active et une documentation bien détaillée fournissant de nombreux exemples.

Cypress offre un large éventail de fonctionnalités permettant de tester l'ensemble de votre application web (en responsive design bien sûr). Le framework est également très modulable en pouvant surcharger des comportements natifs, ajouter de nouvelles fonctions ou d'autres librairies. Il est également possible d'y injecter d'autres frameworks JS.

Les rapports d'erreurs, les captures d'écrans, les vidéos de débogages et tests en temps réels sont réellement un atout majeur à cette solution qui reste très agréable à utiliser au quotidien.

Tout cela se réalise en gardant de très bonnes performances, ce qui me fait pencher ma préférence vers Cypress par rapport à Selenim notamment.