Component Testing

Testing Library

O Testing Library ajuda você a testar componentes da maneira que um usuário os experimenta. Faça consultas por role e texto, interaja com eventos reais e pare de testar detalhes de implementação.

intermediate13 min readUpdated 15 de set. de 2026
Button.test.jsx
jsx
// Button.test.jsx
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { Button } from "./Button";

test("calls onClick when clicked", async () => {
  const onClick = vi.fn();
  render(<Button onClick={onClick}>Save</Button>);

  await userEvent.click(screen.getByRole("button", { name: "Save" }));

  expect(onClick).toHaveBeenCalledOnce();
});
Mantido por
A equipe do Testing Library
Frameworks
React, Vue, Svelte, Angular
Queries
Por role, label e texto
Eventos
userEvent
Async
findBy, waitFor
Filosofia
Testar a experiência do usuário

Por que importa

Por que o Testing Library mudou os testes de componentes

Acessível por padrão

Consultar por role e nome acessível incentiva a criação de marcações semânticas e amigáveis para leitores de tela.

Resistente a refatorações

Testes que utilizam a visão do usuário sobre a página sobrevivem a mudanças internas em componentes e estados.

Funciona com qualquer runner

O Testing Library é agnóstico ao runner, combinando perfeitamente com Vitest, Jest ou qualquer outro framework.

O panorama completo

As três ideias por trás do Testing Library

Consulte o DOM da maneira que os usuários encontram as coisas, interaja com eventos reais e faça asserções sobre o que o usuário vê.

Queries

Encontrar

Localize elementos por sua role, label, texto ou outros atributos visíveis ao usuário.

userEvent

Interagir

Simule interações reais do usuário, como digitar, clicar e navegar com a tecla Tab.

Assertions

Verificar

Faça asserções sobre o que o usuário vê, utilizando matchers do jest-dom para o estado do DOM.

Testing Library em resumo

O núcleo do Testing Library

getByRole

A query preferida, correspondendo a como as tecnologias assistivas encontram elementos.

getByLabelText

Encontre controles de formulário por sua label associada, exatamente como os usuários fazem.

getByText

Localize elementos por seu conteúdo de texto visível.

userEvent

Dispare eventos realistas, incluindo foco, digitação e interação via teclado.

findBy e waitFor

Aguarde a aparição de elementos quando as atualizações forem assíncronas.

jest-dom matchers

toBeInTheDocument, toHaveTextContent, toBeDisabled e mais.

Uma breve historia

Do Enzyme aos testes centrados no usuário

  1. 2018

    React Testing Library

    Kent C. Dodds lança uma pequena biblioteca que testa componentes através do DOM.

    18
  2. 2019

    A família Testing Library

    O núcleo é extraído e surgem adaptadores para Vue, Svelte, Angular e outros.

    19
  3. 2021

    userEvent amadurece

    O userEvent torna-se a maneira recomendada de simular interações.

    21
  4. 2022

    Enzyme depreciado

    A abordagem baseada em detalhes de implementação declina e os testes centrados no usuário tornam-se a norma.

    22
  5. Hoje

    O padrão

    O Testing Library é a abordagem padrão para testes de componentes em diversos frameworks.

    Hoje

O guia completo

Testing Library: Tudo que voce precisa saber

O que é Testing Library?

Testing Library é uma família de bibliotecas que ajudam você a testar componentes de UI da maneira que um usuário os experimenta. Em vez de acessar as entranhas de um componente, você o renderiza, encontra os elementos como uma pessoa faria — por seu role, label ou texto visível — e interage com eles através de eventos realistas.

A ideia central é uma reação aos testes baseados em detalhes de implementação. Abordagens mais antigas renderizavam um componente e então faziam asserções sobre o estado interno, props ou uma estrutura específica do DOM. Esses testes quebravam a cada refatoração, enquanto capturavam pouquíssimos bugs reais. Testing Library inverte a perspectiva: se o usuário consegue ver e usar, você consegue testar, e o teste sobrevive a mudanças na forma como o componente funciona internamente.

Renderização e consultas

Você renderiza um componente e, em seguida, consulta o DOM resultante através de screen.

// LoginForm.test.jsx
import { render, screen } from "@testing-library/react";
import { LoginForm } from "./LoginForm";

test("shows the email field", () => {
  render(<LoginForm />);

  expect(screen.getByLabelText("Email")).toBeInTheDocument();
  expect(screen.getByRole("button", { name: "Sign in" })).toBeInTheDocument();
});

screen é a superfície de consulta recomendada. Ela pesquisa todo o documento renderizado, o que reflete a forma como um usuário vê a página, em vez de focar em um container específico.

Escolhendo a query certa

A Testing Library fornece diversas queries, e a ordem de prioridade importa. Prefira aquelas que estão mais próximas da perspectiva do usuário:

  1. getByRole — botões, links, cabeçalhos, inputs e mais, correspondidos pelo nome acessível. Esta é a melhor opção padrão.
  2. getByLabelText — controles de formulário encontrados por seu label.
  3. getByPlaceholderText — quando o placeholder é o único label disponível.
  4. getByText — conteúdo de texto não interativo.
  5. getByDisplayValue — o valor atual de um elemento de formulário.
  6. getByAltText — imagens pelo seu texto alternativo (alt text).
  7. getByTitle e getByTestId — últimos recursos.
// queries.jsx
screen.getByRole("heading", { level: 1, name: "Dashboard" });
screen.getByLabelText("Password");
screen.getByText("Welcome back");
screen.getByAltText("Company logo");
screen.getByTestId("chart");

getByRole é poderosa porque serve também como uma verificação de acessibilidade. Se um controle não possui um nome acessível, a query falha — o que significa que sua marcação provavelmente também é inacessível.

Cada query possui variantes: getBy lança um erro se nada for correspondido, queryBy retorna null, e findBy retorna uma promise que aguarda. Use queryBy para afirmar que algo está ausente, e findBy após uma atualização assíncrona.

Interagindo com userEvent

userEvent simula a sequência completa de eventos que um usuário real gera.

// Search.test.jsx
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { Search } from "./Search";

test("submits the query", async () => {
  const onSearch = vi.fn();
  render(<Search onSearch={onSearch} />);

  await userEvent.type(screen.getByLabelText("Search"), "vitest");
  await userEvent.click(screen.getByRole("button", { name: "Go" }));

  expect(onSearch).toHaveBeenCalledWith("vitest");
});

userEvent gerencia eventos de foco, teclado e ponteiro em conjunto, o que captura bugs que um único fireEvent.change deixaria passar. Prefira utilizá-lo para tudo, exceto nos raros casos em que ele não cubra a necessidade.

Comportamento assíncrono

A maioria dos componentes é atualizada de forma assíncrona, seja por meio de um fetch, um timer ou uma transição. Use findBy e waitFor em vez de delays arbitrários.

// Users.test.jsx
test("renders users after loading", async () => {
  render(<Users />);

  expect(screen.getByText("Loading…")).toBeInTheDocument();

  const items = await screen.findAllByRole("listitem");
  expect(items).toHaveLength(3);
});

findBy aguarda por um elemento correspondente e falha com uma mensagem útil caso ele nunca apareça. waitFor serve para aguardar por uma asserção ou uma condição que não seja apenas a busca por um elemento. Nunca utilize timeouts reais; eles tornam os testes lentos e instáveis (flaky).

Asserts com jest-dom

O pacote complementar @testing-library/jest-dom adiciona matchers que tornam a leitura do estado do DOM mais natural.

// matchers.test.jsx
expect(button).toBeDisabled();
expect(input).toHaveValue("[email protected]");
expect(dialog).not.toBeInTheDocument();
expect(heading).toHaveTextContent("Dashboard");
expect(link).toHaveAttribute("href", "/docs");

Esses matchers deixam a intenção mais clara do que verificações brutas de propriedades do DOM e geram mensagens de erro melhores.

Testes com foco em acessibilidade

Como o getByRole depende de roles e nomes acessíveis, escrever testes dessa forma revela problemas de acessibilidade precocemente. Se você não consegue encontrar um botão por role, usuários de leitores de tela também não conseguirão. Adicionar getByRole e toHaveAccessibleName aos seus testes é uma das maneiras mais baratas de melhorar a acessibilidade e, frequentemente, substitui a necessidade de uma auditoria automatizada separada.

Testing Library em diferentes frameworks

A biblioteca possui adaptadores para React, Vue, Svelte, Angular e outros. A API de query é compartilhada, portanto, o modelo mental é transferível mesmo que a configuração seja diferente. O adaptador para React é o mais utilizado e o que será demonstrado aqui.

Melhores práticas

  • Faça a busca primeiro por role, depois por label e então por texto; use test ids apenas como último recurso.
  • Use userEvent em vez de fireEvent.
  • Aguarde por findBy e waitFor em vez de utilizar delays.
  • Faça asserções sobre o que o usuário vê, não sobre o estado interno.
  • Mantenha os testes focados em apenas um comportamento cada.
  • Faça a limpeza automaticamente entre os testes; o Testing Library já faz isso por padrão.
  • Trate um getByRole falho como uma dica de que existe um problema de acessibilidade.

Erros comuns

  • Recorrer ao container.querySelector e testar nomes de classes.
  • Usar fireEvent quando userEvent capturaria mais casos.
  • Esperas arbitrárias com setTimeout em vez de findBy.
  • Tirar snapshots de toda a árvore renderizada.
  • Fazer asserções no estado ou props do componente em vez de no DOM.
  • Adicionar test ids em tudo e perder os benefícios de acessibilidade.

Próximos passos

A Testing Library é a camada de componentes de uma estratégia de testes sólida. Execute-a com Vitest ou Jest, aprofunde seus conhecimentos em React para que os componentes sejam testáveis e cubra jornadas completas com Playwright. Agora, escolha um componente que você já criou e escreva um teste sob a perspectiva do usuário.

Encontrando um elemento

Consulte por role para que o teste corresponda a como um usuário e a tecnologia assistiva encontram o controle, e falhe quando ele não for acessível.

Preferir
const button = screen.getByRole("button", {
  name: "Save",
});
Evitar
const button = container.querySelector(
  ".btn.btn-primary",
);

Simulando interação

O userEvent dispara a sequência completa de eventos que um usuário real produz, incluindo foco e comportamento do teclado.

Preferir
await userEvent.type(
  screen.getByLabelText("Email"),
  "[email protected]",
);
Evitar
fireEvent.change(
  screen.getByLabelText("Email"),
  { target: { value: "[email protected]" } },
);

Perguntas frequentes

Perguntas frequentes

Keep learning

Related topics from the roadmap.

$ comecar a aprender

Pronto para aprender Testing Library?

Nosso tutorial interativo te guia por Testing Library passo a passo — com quizzes e codigo real que voce pode executar no navegador.