Saltar al contenido principal

Configuración

[Traducción Beta No Oficial]

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

React Testing Library no requiere configuración para ser utilizada. Sin embargo, existen acciones que puedes implementar al configurar tu framework de pruebas para reducir código repetitivo. En esta documentación demostraremos la configuración con Jest, pero deberías poder realizar ajustes similares con cualquier framework de pruebas (React Testing Library no exige el uso de Jest).

Configuración Global

Añadir opciones a tu configuración global de pruebas puede simplificar la preparación y limpieza de tests en archivos individuales.

Renderizado personalizado

Suele ser útil definir un método de renderizado personalizado que incluya elementos como proveedores de contexto global, almacenes de datos, etc. Para disponer de esto globalmente, un enfoque consiste en crear un archivo de utilidades que reexporte todo desde React Testing Library. Puedes sustituir React Testing Library por este archivo en todas tus importaciones. Consulta más abajo para implementar tu archivo de utilidades sin rutas relativas.

El siguiente ejemplo configura proveedores de datos usando la opción wrapper de render.

my-component.test.jsx
- import { render, fireEvent } from '@testing-library/react';
+ import { render, fireEvent } from '../test-utils';
test-utils.jsx
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}

Nota

Las versiones de Babel anteriores a la 7 generan un error al intentar sobrescribir la exportación nombrada en el ejemplo anterior. Consulta #169 y la solución alternativa más abajo.

Workaround for Babel 6

You can use CommonJS modules instead of ES modules, which should work in Node:

test-utils.js
const rtl = require('@testing-library/react')

const customRender = (ui, options) =>
rtl.render(ui, {
myDefaultOption: 'something',
...options,
})

module.exports = {
...rtl,
render: customRender,
}

Añadir consultas personalizadas

Nota

Generalmente no deberías necesitar crear consultas personalizadas para react-testing-library. Cuando lo hagas, considera si tus nuevas consultas fomentan pruebas centradas en el usuario, evitando detalles de implementación.

Puedes definir consultas personalizadas como se describe en la documentación de Consultas Personalizadas o mediante el asistente buildQueries. Luego podrás utilizarlas en cualquier llamada a render mediante la opción queries. Para disponer de ellas globalmente, añádelas a tu método de renderizado personalizado como se muestra a continuación.

En el siguiente ejemplo, se crean nuevas variantes de consulta para obtener elementos mediante data-cy, una convención de "ID de prueba" mencionada en la documentación de Cypress.io.

custom-queries.js
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,
}

Puedes sobrescribir o añadir las nuevas consultas mediante la función render pasando la opción queries.

Para añadir consultas personalizadas globalmente, define versiones personalizadas de render, screen y within:

test-utils.js
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}

Luego puedes emplear tus consultas personalizadas como cualquier otra consulta:

const {getByDataCy} = render(<Component />)

expect(getByDataCy('my-component')).toHaveTextContent('Hello')

Configuración de Jest con utilidades de prueba

Para que tu archivo de pruebas personalizado sea accesible en tus archivos de prueba de Jest sin usar importaciones relativas (../../test-utils), añade la carpeta que contiene el archivo a la opción moduleDirectories de Jest.

Esto permitirá importar todos los archivos .js en el directorio test-utils sin usar ../.

my-component.test.js
- import { render, fireEvent } from '../test-utils';
+ import { render, fireEvent } from 'test-utils';
jest.config.js
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 usas TypeScript, integra esto en tu tsconfig.json. Si usas Create React App sin TypeScript, guárdalo en jsconfig.json.

tsconfig.json
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"test-utils": ["./utils/test-utils"]
}
}
}

Jest 28

Si usas Jest 28 o superior, el paquete jest-environment-jsdom ahora debe instalarse por separado.

npm install --save-dev jest-environment-jsdom

jsdom tampoco es el entorno predeterminado. Puedes habilitar jsdom globalmente editando jest.config.js:

jest.config.js
 module.exports = {
+ testEnvironment: 'jsdom',
// ... other options ...
}

O si solo necesitas jsdom en algunas de tus pruebas, puedes habilitarlo cuando sea necesario usando docblocks:

/**
* @jest-environment jsdom
*/

Jest 27

Si estás usando una versión reciente de Jest (27), jsdom ya no es el entorno predeterminado. Puedes habilitar jsdom globalmente editando jest.config.js:

jest.config.js
 module.exports = {
+ testEnvironment: 'jest-environment-jsdom',
// ... other options ...
}

O si solo necesitas jsdom en algunas de tus pruebas, puedes habilitarlo cuando sea necesario usando docblocks:

/**
* @jest-environment jsdom
*/

Jest 24 (o inferior) y valores predeterminados

Si usas Jest versión 24 o inferior con la configuración predeterminada, se recomienda usar el paquete jest-environment-jsdom-fifteen ya que Jest utiliza una versión del entorno jsdom que carece de características y correcciones requeridas por React Testing Library.

Primero, instala jest-environment-jsdom-fifteen.

npm install --save-dev jest-environment-jsdom-fifteen

Luego especifica jest-environment-jsdom-fifteen como testEnvironment:

jest.config.js
 module.exports = {
+ testEnvironment: 'jest-environment-jsdom-fifteen',
// ... other options ...
}

Uso sin Jest

Si ejecutas tus pruebas en el navegador con webpack (o similar), React Testing Library debería funcionar sin configuración adicional. Sin embargo, la mayoría de usuarios usan React Testing Library con Jest y testEnvironment configurado como jest-environment-jsdom (configuración predeterminada en Jest 26 y anteriores).

jsdom es una implementación JavaScript pura de las APIs DOM y del navegador que se ejecuta en Node. Si no usas Jest pero quieres ejecutar pruebas en Node, debes instalar jsdom manualmente. Existe también el paquete global-jsdom para configurar el entorno global simulando las APIs del navegador.

Primero, instala jsdom y global-jsdom.

npm install --save-dev jsdom global-jsdom

Con mocha, el comando de prueba se vería similar a esto:

mocha --require global-jsdom/register

Omitir la limpieza automática

Cleanup se ejecuta automáticamente después de cada prueba por defecto si tu framework soporta el global afterEach (como mocha, Jest y Jasmine). Puedes omitir esta limpieza automática configurando la variable de entorno RTL_SKIP_AUTO_CLEANUP en 'true'. Usa cross-env así:

cross-env RTL_SKIP_AUTO_CLEANUP=true jest

Para simplificar, también puedes importar @testing-library/react/dont-cleanup-after-each que logra lo mismo. Asegúrate de hacerlo antes de importar @testing-library/react. En Jest usa la configuración setupFiles:

{
// ... other jest config
setupFiles: ['@testing-library/react/dont-cleanup-after-each']
}

O con el flag -r de mocha:

mocha --require @testing-library/react/dont-cleanup-after-each

Alternativamente, importa @testing-library/react/pure en las pruebas donde no quieras ejecutar cleanup, evitando que afterEach se configure automáticamente.

Limpieza automática en modo watch de Mocha

Al usar Mocha en modo watch, la limpieza global registrada solo se ejecuta la primera vez después de cada prueba. Las ejecuciones posteriores fallarán con error TestingLibraryElementError: Found multiple elements.

Para habilitar la limpieza automática en modo watch de Mocha, agrega un root hook de limpieza. Crea un archivo mocha-watch-cleanup-after-each.js con este contenido:

mocha-watch-cleanup-after-each.js
const {cleanup} = require('@testing-library/react')

exports.mochaHooks = {
afterEach() {
cleanup()
},
}

Y regístralo usando el flag -r de mocha:

mocha --require ./mocha-watch-cleanup-after-each.js

Limpieza automática en Vitest

Si usas Vitest y quieres limpieza automática, habilita los globales en su archivo de configuración:

vitest.config.ts
import {defineConfig} from 'vitest/config'

export default defineConfig({
test: {
globals: true,
},
})

Si prefieres no habilitar globales, importa cleanup y llámalo manualmente en un hook afterEach de nivel superior:

vitest.config.ts
import {defineConfig} from 'vitest/config'

export default defineConfig({
test: {
setupFiles: ['vitest-cleanup-after-each.ts'],
},
})
vitest-cleanup-after-each.ts
import {cleanup} from '@testing-library/react'
import {afterEach} from 'vitest'

afterEach(() => {
cleanup()
})