Pour débuter avec React, il est recommandé d'utiliser Create React App. Il est prêt à l'emploi et livré avec Jest.
Vous n'aurez qu'à ajouter react-test-renderer pour le rendu des instantanés (snapshots). Principalement, ce package facilite la capture d'élément du DOM rendu par un composant React DOM ou React Native sans utiliser de navigateur ou de jsdom.
npm install --save-dev react-test-renderer
Lancer les tests
Vous verrez dans votre fichier package.json le script "test" :
"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" },
Il vous suffit donc de la lancer la commande suivante dans la console :
npm test
La console devrait vous renvoyer le message suivant :
Watch Usage › Press a to run all tests. › Press f to run only failed tests. › Press q to quit watch mode. › Press p to filter by a filename regex pattern. › Press t to filter by a test name regex pattern. › Press Enter to trigger a test run.
Pour commencer, choisissez d'appuyer sur la touche "a"
Création d'un premier test custom
Si vous avez utilisé create-react-app, vous devriez trouver le fichier App.test.tsx. Ce qui sous-entend que l'on peut tester une application React composant par composant. Par défaut, voici le fichier en question :
import React from 'react'; import { render, screen } from '@testing-library/react'; import App from './App'; test('renders learn react link', () => { render(<App />); const linkElement = screen.getByText(/learn react/i); expect(linkElement).toBeInTheDocument(); });
Imaginons que l'on veuille s'assurer que l'application contient bien un h1 avec pour contenu "Memo" (avec ou sans majuscule). Voici ce que la fonction test pourrait devenir :
import { render, screen } from '@testing-library/react';
import App from './App';
test('h1 contient le texte Memo', () => { render(<App />); const titleElement = screen.getByRole('heading', {level: 1}) expect(titleElement).toBeInTheDocument(); expect(titleElement?.textContent).toMatch(/MEMO/i); });
Vous voyez que ce code comporte :
- une requête (query) : getByRole
- deux tests : toBeInTheDocument et toMatch
Queries
Référence : https://testing-library.com/docs/queries/about
Les requêtes sont les méthodes que Testing Library vous propose pour rechercher des éléments sur la page. Il existe plusieurs types de requêtes ("get", "find", "query"); la différence entre eux est de savoir si la requête générera une erreur si aucun élément n'est trouvé ou si elle renverra une promesse et réessayera. Selon le contenu de la page que vous sélectionnez, différentes requêtes peuvent être plus ou moins appropriées. Consultez le guide des priorités pour obtenir des recommandations sur la façon d'utiliser les requêtes sémantiques pour tester votre page de la manière la plus accessible.
Vous verrez dans la documentation qu'il existe plusieurs type de query :
- ByRole
- ByLabelText
- ByPlaceholderText
- ByText
- ByDisplayValue
- ByAltText
- ByTitle
- ByTestId
Tests
Référence : https://jestjs.io/docs/expect
Lorsque vous écrivez des tests, vous devez souvent vérifier que les valeurs remplissent certaines conditions. la fonction expect vous donne accès à un certain nombre de "matchers" dont voici les principaux :
- .toBe(value)
- .toHaveBeenCalledTimes(number)
- .toHaveReturned()
- .toHaveLength(number)
- .toHaveProperty(keyPath, value?)
- .toBeDefined()
- .toBeFalsy()
- .toBeGreaterThan(number | bigint)
- .toBeGreaterThanOrEqual(number | bigint)
- .toBeLessThan(number | bigint)
- .toBeLessThanOrEqual(number | bigint)
- .toBeInstanceOf(Class)
- .toBeNull()
- .toBeTruthy()
- .toBeUndefined()
- .toEqual(value)
- .toMatch(regexp | string)
- .toStrictEqual(value)
- .toThrow(error?)
A noter : jest-dom ajoute un certain nombre de "watchers" :
- toBeDisabled
- toBeEnabled
- toBeEmpty
- toBeInTheDocument
- toBeInvalid
- toBeRequired
- toBeValid
- toBeVisible
- toContainElement
- toContainHTML
- toHaveAttribute
- toHaveClass
- toHaveFocus
- toHaveFormValues
- toHaveStyle
- toHaveTextContent
- toHaveValue