Configuration
Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →
React Testing Library ne nécessite aucune configuration pour être utilisé. Cependant,
vous pouvez optimiser votre framework de test pour réduire le code répétitif.
Dans cette documentation, nous utiliserons Jest pour les démonstrations, mais
vous pouvez adapter ces principes à
n'importe quel framework de test (React Testing Library
fonctionne indépendamment de Jest).
Configuration globale
Ajouter des options à votre configuration de test globale peut simplifier l'initialisation et le nettoyage des tests dans chaque fichier.
Rendu personnalisé
Il est souvent utile de définir une méthode de rendu personnalisée incluant
des éléments comme des fournisseurs de contexte globaux, des stores de données, etc.
Pour la rendre disponible globalement, une approche consiste à créer un fichier utilitaire
qui réexporte tout depuis React Testing Library. Vous pouvez remplacer les imports
de React Testing Library par ce fichier. Consultez la section
ci-dessous pour éviter les imports relatifs.
L'exemple ci-dessous configure des fournisseurs de données via l'option
wrapper de render.
- JavaScript
- TypeScript
- import { render, fireEvent } from '@testing-library/react';
+ import { render, fireEvent } from '../test-utils';
import React from 'react'
import {render} from '@testing-library/react'
import {ThemeProvider} from 'my-ui-lib'
import {TranslationProvider} from 'my-i18n-lib'
import defaultStrings from 'i18n/en-x-default'
const AllTheProviders = ({children}) => {
return (
<ThemeProvider theme="light">
<TranslationProvider messages={defaultStrings}>
{children}
</TranslationProvider>
</ThemeProvider>
)
}
const customRender = (ui, options) =>
render(ui, {wrapper: AllTheProviders, ...options})
// re-export everything
export * from '@testing-library/react'
// override render method
export {customRender as render}
- import { render, fireEvent } from '@testing-library/react';
+ import { render, fireEvent } from '../test-utils';
import React, {ReactElement} from 'react'
import {render, RenderOptions} from '@testing-library/react'
import {ThemeProvider} from 'my-ui-lib'
import {TranslationProvider} from 'my-i18n-lib'
import defaultStrings from 'i18n/en-x-default'
const AllTheProviders = ({children}: {children: React.ReactNode}) => {
return (
<ThemeProvider theme="light">
<TranslationProvider messages={defaultStrings}>
{children}
</TranslationProvider>
</ThemeProvider>
)
}
const customRender = (
ui: ReactElement,
options?: Omit<RenderOptions, 'wrapper'>,
) => render(ui, {wrapper: AllTheProviders, ...options})
export * from '@testing-library/react'
export {customRender as render}
Note
Les versions de Babel antérieures à 7 génèrent une erreur lors de la surcharge d'export nommé dans l'exemple ci-dessus. Voir #169 et la solution alternative ci-dessous.
Workaround for Babel 6
You can use CommonJS modules instead of ES modules, which should work in Node:
const rtl = require('@testing-library/react')
const customRender = (ui, options) =>
rtl.render(ui, {
myDefaultOption: 'something',
...options,
})
module.exports = {
...rtl,
render: customRender,
}
Ajouter des requêtes personnalisées
Note
En règle générale, vous ne devriez pas avoir besoin de créer des requêtes personnalisées pour react-testing-library. Si vous le faites, vérifiez que vos nouvelles requêtes encouragent des tests centrés sur l'utilisateur, sans tester les détails d'implémentation.
Vous pouvez définir vos propres requêtes comme décrit dans la documentation
Requêtes personnalisées, ou via
l'utilitaire buildQueries.
Vous pourrez ensuite les utiliser dans tout appel à render via l'option queries.
Pour les rendre disponibles globalement, ajoutez-les à votre méthode de rendu personnalisée :
Dans cet exemple, nous créons des variantes de requêtes pour sélectionner
des éléments par data-cy, une convention de "test ID" mentionnée dans la
documentation Cypress.io.
- JavaScript
- TypeScript
import {queryHelpers, buildQueries} from '@testing-library/react'
// The queryAllByAttribute is a shortcut for attribute-based matchers
// You can also use document.querySelector or a combination of existing
// testing library utilities to find matching nodes for your query
const queryAllByDataCy = (...args) =>
queryHelpers.queryAllByAttribute('data-cy', ...args)
const getMultipleError = (c, dataCyValue) =>
`Found multiple elements with the data-cy attribute of: ${dataCyValue}`
const getMissingError = (c, dataCyValue) =>
`Unable to find an element with the data-cy attribute of: ${dataCyValue}`
const [
queryByDataCy,
getAllByDataCy,
getByDataCy,
findAllByDataCy,
findByDataCy,
] = buildQueries(queryAllByDataCy, getMultipleError, getMissingError)
export {
queryByDataCy,
queryAllByDataCy,
getByDataCy,
getAllByDataCy,
findAllByDataCy,
findByDataCy,
}
import {
queryHelpers,
buildQueries,
Matcher,
MatcherOptions,
} from '@testing-library/react'
// The queryAllByAttribute is a shortcut for attribute-based matchers
// You can also use document.querySelector or a combination of existing
// testing library utilities to find matching nodes for your query
const queryAllByDataCy = (
container: HTMLElement,
id: Matcher,
options?: MatcherOptions | undefined,
) => queryHelpers.queryAllByAttribute('data-cy', container, id, options)
const getMultipleError = (c, dataCyValue) =>
`Found multiple elements with the data-cy attribute of: ${dataCyValue}`
const getMissingError = (c, dataCyValue) =>
`Unable to find an element with the data-cy attribute of: ${dataCyValue}`
const [
queryByDataCy,
getAllByDataCy,
getByDataCy,
findAllByDataCy,
findByDataCy,
] = buildQueries(queryAllByDataCy, getMultipleError, getMissingError)
export {
queryByDataCy,
queryAllByDataCy,
getByDataCy,
getAllByDataCy,
findAllByDataCy,
findByDataCy,
}
Vous pouvez ensuite intégrer ces nouvelles requêtes via la fonction render
en passant l'option queries.
Pour ajouter globalement des requêtes personnalisées, définissez vos versions
modifiées de render, screen et within :
- JavaScript
- TypeScript
import {render, queries, within} from '@testing-library/react'
import * as customQueries from './custom-queries'
const allQueries = {
...queries,
...customQueries,
}
const customScreen = within(document.body, allQueries)
const customWithin = element => within(element, allQueries)
const customRender = (ui, options) =>
render(ui, {queries: allQueries, ...options})
// re-export everything
export * from '@testing-library/react'
// override render method
export {customScreen as screen, customWithin as within, customRender as render}
import {render, queries, within, RenderOptions} from '@testing-library/react'
import * as customQueries from './custom-queries'
import {ReactElement} from 'react'
const allQueries = {
...queries,
...customQueries,
}
const customScreen = within(document.body, allQueries)
const customWithin = (element: ReactElement) => within(element, allQueries)
const customRender = (
ui: ReactElement,
options?: Omit<RenderOptions, 'queries'>,
) => render(ui, {queries: allQueries, ...options})
export * from '@testing-library/react'
export {customScreen as screen, customWithin as within, customRender as render}
Utilisez ensuite vos requêtes personnalisées comme n'importe quelle autre requête :
const {getByDataCy} = render(<Component />)
expect(getByDataCy('my-component')).toHaveTextContent('Hello')
Configurer Jest avec des utilitaires de test
Pour importer votre fichier de test personnalisé sans utiliser de chemins relatifs
(../../test-utils), ajoutez son dossier à l'option moduleDirectories de Jest.
Cela rendra tous les fichiers .js du dossier test-utils importables
sans ../.
- import { render, fireEvent } from '../test-utils';
+ import { render, fireEvent } from 'test-utils';
module.exports = {
moduleDirectories: [
'node_modules',
+ // add the directory with the test-utils.js file, for example:
+ 'utils', // a utility folder
+ __dirname, // the root directory
],
// ... other options ...
}
Si vous utilisez TypeScript, intégrez ceci dans votre tsconfig.json.
Avec Create React App sans TypeScript, utilisez jsconfig.json.
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"test-utils": ["./utils/test-utils"]
}
}
}
Jest 28
À partir de Jest 28, le package jest-environment-jsdom doit être installé séparément.
- npm
- Yarn
npm install --save-dev jest-environment-jsdom
yarn add --dev jest-environment-jsdom
jsdom n'est plus l'environnement par défaut. Activez jsdom globalement en modifiant jest.config.js :
module.exports = {
+ testEnvironment: 'jsdom',
// ... other options ...
}
Ou si vous n'avez besoin de jsdom que pour certains tests, vous pouvez l'activer ponctuellement en utilisant des docblocks :
/**
* @jest-environment jsdom
*/
Jest 27
Si vous utilisez une version récente de Jest (27), jsdom n'est plus l'environnement par défaut. Vous pouvez activer jsdom globalement en modifiant jest.config.js :
module.exports = {
+ testEnvironment: 'jest-environment-jsdom',
// ... other options ...
}
Ou si vous n'avez besoin de jsdom que pour certains tests, vous pouvez l'activer ponctuellement en utilisant des docblocks :
/**
* @jest-environment jsdom
*/
Jest 24 (ou inférieur) et configurations par défaut
Si vous utilisez Jest version 24 ou inférieure avec la configuration par défaut, nous recommandons d'utiliser le package jest-environment-jsdom-fifteen car Jest emploie une version de l'environnement jsdom qui manque certaines fonctionnalités et corrections requises par React Testing Library.
D'abord, installez jest-environment-jsdom-fifteen.
- npm
- Yarn
npm install --save-dev jest-environment-jsdom-fifteen
yarn add --dev jest-environment-jsdom-fifteen
Puis spécifiez jest-environment-jsdom-fifteen comme testEnvironment :
module.exports = {
+ testEnvironment: 'jest-environment-jsdom-fifteen',
// ... other options ...
}
Utilisation sans Jest
Si vous exécutez vos tests dans un navigateur via webpack (ou similaire), React Testing Library devrait fonctionner immédiatement. Cependant, la plupart des utilisateurs de React Testing Library l'emploient avec le framework de test Jest en configurant testEnvironment sur jest-environment-jsdom (configuration par défaut pour Jest 26 et antérieur).
jsdom est une implémentation JavaScript pure du DOM et des APIs navigateur qui s'exécute dans Node. Si vous n'utilisez pas Jest et souhaitez lancer vos tests dans Node, vous devez installer jsdom vous-même. Il existe également un package appelé global-jsdom pour configurer l'environnement global et simuler les APIs navigateur.
D'abord, installez jsdom et global-jsdom.
- npm
- Yarn
npm install --save-dev jsdom global-jsdom
yarn add --dev jsdom global-jsdom
Avec mocha, la commande de test ressemblerait à ceci :
mocha --require global-jsdom/register
Désactivation du nettoyage automatique
Cleanup est appelé automatiquement après chaque test par défaut si votre framework de test supporte la globale afterEach (comme mocha, Jest et Jasmine). Cependant, vous pouvez désactiver ce nettoyage automatique en définissant la variable d'environnement RTL_SKIP_AUTO_CLEANUP à 'true'. Vous pouvez le faire avec cross-env comme suit :
cross-env RTL_SKIP_AUTO_CLEANUP=true jest
Pour simplifier, vous pouvez aussi importer @testing-library/react/dont-cleanup-after-each qui produit le même effet. Assurez-vous de le faire avant d'importer @testing-library/react. Avec Jest, utilisez la configuration setupFiles :
{
// ... other jest config
setupFiles: ['@testing-library/react/dont-cleanup-after-each']
}
Ou avec l'option -r de mocha :
mocha --require @testing-library/react/dont-cleanup-after-each
Alternative : importer @testing-library/react/pure dans tous vos tests où vous ne voulez pas exécuter le cleanup - dans ce cas afterEach ne sera pas configuré automatiquement.
Nettoyage automatique en mode watch de Mocha
En utilisant Mocha en mode watch, le nettoyage global n'est exécuté qu'une seule fois après chaque test. Les exécutions suivantes échoueront probablement avec une erreur TestingLibraryElementError: Found multiple elements.
Pour activer le nettoyage automatique en mode watch de Mocha, ajoutez un hook racine de nettoyage. Créez un fichier mocha-watch-cleanup-after-each.js avec ce contenu :
const {cleanup} = require('@testing-library/react')
exports.mochaHooks = {
afterEach() {
cleanup()
},
}
Et enregistrez-le via l'option -r de mocha :
mocha --require ./mocha-watch-cleanup-after-each.js
Nettoyage automatique avec Vitest
Si vous utilisez Vitest et souhaitez activer le nettoyage automatique, vous pouvez activer les globales via son fichier de configuration :
import {defineConfig} from 'vitest/config'
export default defineConfig({
test: {
globals: true,
},
})
Si vous ne voulez pas activer les globales, importez cleanup et appelez-le manuellement dans un hook afterEach global :
import {defineConfig} from 'vitest/config'
export default defineConfig({
test: {
setupFiles: ['vitest-cleanup-after-each.ts'],
},
})
import {cleanup} from '@testing-library/react'
import {afterEach} from 'vitest'
afterEach(() => {
cleanup()
})