Configuração
Esta página foi traduzida por PageTurner AI (beta). Não é oficialmente endossada pelo projeto. Encontrou um erro? Reportar problema →
O React Testing Library não requer nenhuma configuração para ser utilizado. Contudo,
existem algumas ações que você pode realizar ao configurar seu framework de testes para
reduzir código repetitivo. Nesta documentação demonstraremos a configuração do Jest, mas
você deve conseguir fazer ações similares com
qualquer framework de testes (o React Testing Library não
exige que você use Jest).
Configuração Global
Adicionar opções à sua configuração global de testes pode simplificar a preparação e finalização de testes em arquivos individuais.
Renderização personalizada
Frequentemente é útil definir um método de renderização personalizado que inclua elementos como
provedores de contexto global, armazenamentos de dados, etc. Para disponibilizar isso globalmente, uma
abordagem é definir um arquivo utilitário que reexporta tudo do
React Testing Library. Você pode substituir as importações do React Testing Library por este arquivo em
todas as suas importações. Veja abaixo para uma forma de
tornar seu arquivo de utilitários de teste acessível sem usar caminhos relativos.
O exemplo abaixo configura provedores de dados usando a opção wrapper
do 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}
Nota
Versões do Babel anteriores à 7 lançam um erro ao tentar sobrescrever a exportação nomeada no exemplo acima. Consulte #169 e a solução alternativa abaixo.
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,
}
Adicionar consultas personalizadas
Nota
Geralmente você não precisa criar consultas personalizadas para o react-testing-library. Quando for necessário, considere se suas novas consultas incentivam testes centrados no usuário, sem verificar detalhes de implementação.
Você pode definir suas próprias consultas personalizadas conforme descrito na
documentação de Consultas Personalizadas, ou
através do auxiliar
buildQueries.
Em seguida, você pode usá-las em qualquer chamada de renderização usando a opção queries. Para
disponibilizar as consultas personalizadas globalmente, você pode adicioná-las ao seu método de
renderização personalizado conforme mostrado abaixo.
No exemplo abaixo, um novo conjunto de variantes de consulta é criado para obter
elementos por data-cy, uma convenção de "ID de teste" mencionada na
documentação do 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,
}
Você pode então sobrescrever e anexar as novas consultas através da função de renderização
passando a opção queries.
Se desejar adicionar consultas personalizadas globalmente, você pode fazer isso definindo seus
métodos personalizados de render, screen e 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}
Você pode então usar suas consultas personalizadas como qualquer outra consulta:
const {getByDataCy} = render(<Component />)
expect(getByDataCy('my-component')).toHaveTextContent('Hello')
Configurando o Jest com utilitários de teste
Para tornar seu arquivo de teste personalizado acessível nos arquivos de teste do Jest sem usar importações relativas (../../test-utils), adicione a pasta que contém o arquivo à opção moduleDirectories do Jest.
Isso tornará todos os arquivos .js no diretório test-utils importáveis sem ../.
- 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 ...
}
Se estiver usando TypeScript, mescle isso no seu tsconfig.json. Se estiver
usando Create React App sem TypeScript, salve isso em jsconfig.json.
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"test-utils": ["./utils/test-utils"]
}
}
}
Jest 28
Se estiver usando Jest 28 ou superior, o pacote jest-environment-jsdom agora deve ser instalado separadamente.
- npm
- Yarn
npm install --save-dev jest-environment-jsdom
yarn add --dev jest-environment-jsdom
O jsdom também não é mais o ambiente padrão. Você pode ativar o jsdom
globalmente editando jest.config.js:
module.exports = {
+ testEnvironment: 'jsdom',
// ... other options ...
}
Ou, se só precisa do jsdom em alguns testes, pode habilitá-lo conforme necessário usando docblocks:
/**
* @jest-environment jsdom
*/
Jest 27
Se você está usando uma versão recente do Jest (27), jsdom não é mais o ambiente padrão. Você pode habilitar o jsdom globalmente editando jest.config.js:
module.exports = {
+ testEnvironment: 'jest-environment-jsdom',
// ... other options ...
}
Ou, se só precisa do jsdom em alguns testes, pode habilitá-lo conforme necessário usando docblocks:
/**
* @jest-environment jsdom
*/
Jest 24 (ou inferior) e padrões
Se estiver usando o Jest versão 24 ou inferior com configuração padrão, recomenda-se usar o pacote jest-environment-jsdom-fifteen, pois o Jest utiliza uma versão do ambiente jsdom que carece de alguns recursos e correções exigidos pelo React Testing Library.
Primeiro, instale o jest-environment-jsdom-fifteen.
- npm
- Yarn
npm install --save-dev jest-environment-jsdom-fifteen
yarn add --dev jest-environment-jsdom-fifteen
Em seguida, especifique jest-environment-jsdom-fifteen como o testEnvironment:
module.exports = {
+ testEnvironment: 'jest-environment-jsdom-fifteen',
// ... other options ...
}
Usando sem o Jest
Se você executa seus testes no navegador com webpack (ou similar), o React Testing Library deve funcionar imediatamente. Contudo, a maioria dos usuários utiliza-o com o Jest, tendo testEnvironment configurado como jest-environment-jsdom (padrão no Jest 26 e anteriores).
O jsdom é uma implementação em JavaScript puro das APIs DOM e do navegador que roda no Node. Se não usa Jest e quer executar testes no Node, instale o jsdom manualmente. Existe também o pacote global-jsdom para configurar o ambiente global simulando APIs de navegador.
Primeiro, instale o jsdom e o global-jsdom.
- npm
- Yarn
npm install --save-dev jsdom global-jsdom
yarn add --dev jsdom global-jsdom
Com o Mocha, o comando de teste seria algo assim:
mocha --require global-jsdom/register
Pulando a limpeza automática
Por padrão, Cleanup é chamado automaticamente após cada teste se sua estrutura de teste suportar o global afterEach (como Mocha, Jest e Jasmine). Para desativar, defina a variável de ambiente RTL_SKIP_AUTO_CLEANUP como 'true' usando cross-env:
cross-env RTL_SKIP_AUTO_CLEANUP=true jest
Para simplificar, importe @testing-library/react/dont-cleanup-after-each que faz o mesmo. Certifique-se de fazer isso ANTES de importar @testing-library/react. No Jest, use a configuração setupFiles:
{
// ... other jest config
setupFiles: ['@testing-library/react/dont-cleanup-after-each']
}
Ou com o flag -r do Mocha:
mocha --require @testing-library/react/dont-cleanup-after-each
Alternativamente, importe @testing-library/react/pure nos testes onde não quer a cleanup - o afterEach não será configurado automaticamente.
Limpeza automática no modo watch do Mocha
No modo watch do Mocha, a limpeza global só é executada na primeira vez após cada teste. Execuções subsequentes falharão com erro TestingLibraryElementError: Found multiple elements.
Para habilitar a limpeza automática no modo watch, adicione um root hook de limpeza. Crie um arquivo mocha-watch-cleanup-after-each.js com:
const {cleanup} = require('@testing-library/react')
exports.mochaHooks = {
afterEach() {
cleanup()
},
}
Registre-o usando o flag -r do Mocha:
mocha --require ./mocha-watch-cleanup-after-each.js
Limpeza automática no Vitest
Para que a limpeza automática funcione no Vitest, habilite globais no arquivo de configuração:
import {defineConfig} from 'vitest/config'
export default defineConfig({
test: {
globals: true,
},
})
Se não quiser habilitar globais, importe cleanup e chame-a manualmente num hook afterEach de nível superior:
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()
})