Skip to main content

Les tests

Introduction#

A mesure que la complexité d'une application augmente, la factorisation de notre code devient un enjeu important pour assurer l'efficacité du développement.

Dans ce contexte, il arrive fréquemment que la modification d'un composant ou autre fonction, utilisé à plusieurs endroits dans le code de d'une application, entraîne l'apparition d'un bug imprévu.

Comment se prémunir de ce type de problèmes ? En exprimant systématiquement des exigences pour notre code et en les validant par des tests.

Avec React, il existe des outils pour automatiser ces tests. Nous allons en étudier deux qui sont complémentaires : Jest et React testing Library.

Les types de test#

Quand vous recherchez des informations au sujet des tests sur internet, vous risquez de vous retrouver paralysés devant la myriade de possibilités offertes par le sujet. On regroupe souvent les tests dans quelques grandes catégories :

  • Lest tests unitaires
    • Il s'agit de tester complètement toutes les configurations possibles de la plus petite unité possible de code (une fonction par exemple)
  • Les tests d'intégrations
    • Il s'agit de tester l'intégration de différentes parties du logiciel ensemble
  • Les tests end-to-end
    • Il s'agit de réaliser des tests d'un bout à l'autre d'une application : du clic à la base de données par exemple

Aujourd'hui, nous allons plutôt travailler sur les tests d'intégration, qui sont les plus communs, et bien souvent les plus utiles.

Jest#

Le premier outil que nous allons étudier se nomme Jest. C'est un outil initialement développé par Facebook, qui est très vite devenu la référence dans le domaine du test front-end.

Il s'agit d'un test runner, c'est à dire une bibliothèque Javascript permettant de créer, lancer et structurer des tests.

info

Dans les projets créés avec Create React App, Jest est installé et configuré. Il lancera automatiquement les tests des fichiers dont l'extension est .test.js.

Créez un nouveau fichier test/square.test.js. Ajoutez-y la fonction suivante :

const square = n => {    return n * n}

Cette fonction très simple retourne le nombre qui lui est passé au carré. Nous allons tester si elle fonctionne correctement à l'aide de Jest.

Structure d'un test#

De manière générale, un test est structuré de la manière suivante :

  • un block permettant de déclarer un test et de lui donner un nom
  • l'exécution de la fonction à tester
  • la vérification du résultat

Pour préciser à Jest que nous créons un test, on utilise la fonction test.

Pour décrire le résultat attendu, nous allons utiliser la fonction expect, accompagnée de matchers.

Sans tarder, un exemple :

// La fonction test prend le nom du test, et une fonctiontest('it should return the squared number', () => {    const number = 5    const expected = 25    // On appelle notre fonction    const result = square(number)    // On vérifie que le résultat est celui escompté    expect(result).toEqual(expected)})

Ici, nous utilisons le matcher toEqual permettant de vérifier l'égalité. Il en existe de très nombreux autres, décris dans la documentation de Jest.

Essayez de lancer les tests de votre application :

npm run test

Vous devriez voir apparaître quelque chose de ce type :

jest screenshot

Comme vous pouvez le constater, notre test fonctionne et son nom est bien affiché. Essayez de le modifier pour le faire échouer par exemple.

Quand on fait plusieurs tests sur le même sujet, on a souvent besoin d'ajouter un élément de structure supplémentaire, afin de préciser ce que l'on teste : describe.

Essayez d'entourer votre test avec le code suivant, et d'ajouter un test avec des nombres différents :

describe('square', () => {    // Vos tests ici})

Que remarquez-vous dans la sortie de la console ?

Une fois ceci terminé, faites un commit avec le commentaire "Ex 7 : Running tests" et poussez vers le serveur.

git add .git commit -m 'Ex 7 : Running tests'git push

Jest offre de nombreuses autres possibilités, que vous découvrirez au fur et à mesure.

React Testing Library#

React Testing Library est un projet open source visant à simplifier l'écriture de tests et à encourager de meilleurs pratiques de test. Cette bibliothèque a eu tant de succès qu'elle a même été déclinée pour de nombreuses autres bibliothèques d'affichage et frameworks : Angular, Vue, Svelte...

Le concept est assez simple : il s'agit de donner la possibilité au développeur React "d'afficher" un composant React, c'est à dire d'en produire le code HTML, puis d'interagir ensuite avec : sélectionner des éléments, simuler des actions de l'utilisateur, etc.

note

Dans les projets créés avec Create React App, React Testing Library est déjà installé et configuré pour fonctionner avec Jest.

Rendre des composants#

Pour "afficher" un élément React, nous devons utiliser la méthode render exportée par React Testing Library.

Elle s'utilise de la sorte :

import { render } from '@testing-library/react'// ...render(<MyComponent />)

On peut ensuite accéder à ce qui a été rendu au travers de l'objet screen et de ses sélecteurs.

Une fois l'élément obtenu, il ne nous reste plus qu'à effectuer notre assertion à l'aide d'expect.

Voici un exemple pour un de nos composants les plus simples : Fab.

Créez le fichier suivant, et mettez-y ce contenu :

src/test/Fab.test.js
import { render, screen } from '@testing-library/react'import React from 'react'
import Fab from '../components/Fab'
describe('Fab', () => {    test('should render a button', () => {        // On "affiche" notre composant        render(<Fab />)        // On récupère l'élément en vérifiant qu'il s'agit d'un bouton        expect(screen.getByRole('button')).toBeInTheDocument()    })})

Notez qu'on a utilisé ici le sélecteur getByRole, qui récupère un élément à l'aide de son rôle (ici, un rôle implicite lié au HTML, voir la documentation associée du MDN).

Nous avons ensuite utilisé le matcher toBeInTheDocument pour vérifier que l'élément est bien dans le document. Notez que ce matcher ne fait à l'origine pas partie de Jest, mais est ajouté par React Testing Library.

A l'aide de la documentation de React Testing Library, vérifiez que le composant Alert affiche bien le texte qui lui est passé dans sa prop description.

tip

L'objet screen expose une méthode debug qui affiche ce qui est rendu en HTML dans votre terminal

Une fois ceci terminé, faites un commit avec le commentaire "Ex 8 : Testing Alert" et poussez vers le serveur.

git add .git commit -m 'Ex 8 : Testing Alert'git push

Interagir avec des composants#

Une extension de React Testing Library nommée user-event permet d'interagir avec les composants affichés de manière très simple, de la même façon qu'un utilisateur le ferait.

info

Cette extension est installée dans les projets créés avec Create React App.

A l'aide de l'objet userEvent exportée par cette dernière, on peut simuler une action sur un élément précédemment sélectionné.

Voici un exemple pour le composant Fab :

import userEvent from '@testing-library/user-event'// ...test('it should call its onClick prop when clicked', async() => {    // On créé une fonction de test    const handleClick = jest.fn()    // On affiche le composant Fab    render(<Fab onClick={handleClick} />)    // On simule le click    await userEvent.click(screen.getByRole('button'))    // On vérifie que la fonction  de test a été appelée    expect(handleClick).toHaveBeenCalled()})

Ici, on créé une fonction de test à l'aide de jest.fn(), ce qui nous permet ensuite d'utiliser le matcher toHaveBeenCalled.

En utilisant cette méthode et les documentations à votre disposition, essayez de tester le composant LoginForm.

Une fois ceci terminé, faites un commit avec le commentaire "Ex 9 : Testing LoginForm" et poussez vers le serveur.

git add .git commit -m 'Ex 9 : Testing LoginForm'git push

Tester la gallerie#

En utilisant vos connaissances, essayer d'écrire tous les tests nécessaires au test complet de la gallerie.

tip

Essayez de remplacer la fonction fetch par une fonction Jest pour faire vos tests...

Vous devriez vous rendre compte que ce composant n'affiche rien en cas d'erreur. Faites les changements appropriés.

Une fois ceci terminé, faites un commit avec le commentaire "Ex 10 : Testing Gallery" et poussez vers le serveur.

git add .git commit -m 'Ex 10 : Testing Gallery'git push

Tester le flux de Login#

En utilisant vos connaissances, essayer d'écrire tous les tests nécessaires au test complet du flux de connexion.

Une fois ceci terminé, faites un commit avec le commentaire "Ex 11 : Testing Login" et poussez vers le serveur.

git add .git commit -m 'Ex 11 : Testing Login'git push

Conclusion#

Félicitations, vous avez terminé ce 4ème et dernier TP. Cette initiation aux tests vous permettra peut-être d'utiliser les outils qui vous aideront à produire des applications de meilleure qualité.

N'hésitez pas à vous mettre à la place d'un utilisateur qui manipule votre application quand vous écrivez vos tests, quitte à tester plusieurs composants en même temps s'ils font partie d'une même fonctionnalité.

Pour aller plus loin#

Un tutoriel assez exhaustif a aussi été créé par Robin Wieruch, vous pourrez le trouver sur cette page.

Si vous souhaitez en savoir plus sur le sujet des tests end-to-end, je vous conseille de regarder du côté de Cypress, un framework moderne pour réaliser ces tests. Les exemples sont nombreux à ce sujet sur internet.