Component Testing

Testing Library

Testing Library te ayuda a probar componentes de la misma manera en que los experimenta un usuario. Realiza consultas por rol y texto, interactúa con eventos reales y deja de probar detalles de implementación.

intermediate13 min readUpdated 15 sept 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();
});
Mantenido por
El equipo de Testing Library
Frameworks
React, Vue, Svelte, Angular
Consultas
Por rol, etiqueta y texto
Eventos
userEvent
Asíncrono
findBy, waitFor
Filosofía
Probar la experiencia del usuario

Por que importa

Por qué Testing Library cambió las pruebas de componentes

Accesible por defecto

Consultar por rol y nombre accesible te impulsa hacia un marcado semántico y compatible con lectores de pantalla.

Resistente a refactorizaciones

Las pruebas que utilizan la vista del usuario sobre la página sobreviven a los cambios internos en los componentes y el estado.

Funciona con cualquier runner

Testing Library es agnóstico al runner, combinándose igualmente bien con Vitest, Jest u otro framework.

La imagen completa

Las tres ideas detrás de Testing Library

Consulta el DOM de la misma forma en que los usuarios encuentran las cosas, interactúa con eventos reales y verifica lo que el usuario ve.

Consultas

Encontrar

Localiza elementos por su rol, etiqueta, texto u otros atributos visibles para el usuario.

userEvent

Interactuar

Simula interacciones reales del usuario como escribir, hacer clic y navegar con el tabulador.

Aserciones

Verificar

Verifica lo que el usuario ve, utilizando matchers de jest-dom para el estado del DOM.

Testing Library de un vistazo

El núcleo de Testing Library

getByRole

La consulta preferida, que imita cómo las tecnologías asistivas encuentran los elementos.

getByLabelText

Encuentra controles de formulario por su etiqueta asociada, exactamente como lo hacen los usuarios.

getByText

Localiza elementos por su contenido de texto visible.

userEvent

Dispara eventos realistas, incluyendo el foco, la escritura y la interacción con el teclado.

findBy y waitFor

Espera a que los elementos aparezcan cuando las actualizaciones son asíncronas.

Matchers de jest-dom

toBeInTheDocument, toHaveTextContent, toBeDisabled y más.

Una breve historia

De Enzyme a las pruebas centradas en el usuario

  1. 2018

    React Testing Library

    Kent C. Dodds lanza una pequeña librería que prueba componentes a través del DOM.

    18
  2. 2019

    La familia Testing Library

    Se extrae el núcleo y aparecen adaptadores para Vue, Svelte, Angular y otros.

    19
  3. 2021

    userEvent madura

    userEvent se convierte en la forma recomendada de simular interacciones.

    21
  4. 2022

    Enzyme queda obsoleta

    El enfoque basado en detalles de implementación declina y las pruebas centradas en el usuario se convierten en la norma.

    22
  5. Hoy

    El estándar

    Testing Library es el enfoque predeterminado para las pruebas de componentes en diversos frameworks.

    Hoy

La guia completa

Testing Library: Todo lo que necesitas saber

¿Qué es Testing Library?

Testing Library es una familia de librerías que te ayudan a probar componentes de UI de la misma manera en que los experimenta un usuario. En lugar de acceder a los detalles internos de un componente, lo renderizas, buscas los elementos tal como lo haría una persona —por su rol, etiqueta o texto visible— e interactúas con ellos a través de eventos realistas.

La idea central es una reacción contra las pruebas basadas en detalles de implementación. Los enfoques antiguos renderizaban un componente y luego hacían aserciones sobre el estado interno, las props o una estructura específica del DOM. Esas pruebas se rompían en cada refactorización, aunque detectaban muy pocos errores reales. Testing Library cambia la perspectiva: si el usuario puede verlo y usarlo, puedes probarlo, y la prueba sobrevivirá a los cambios en el funcionamiento interno del componente.

Renderizado y consultas

Renderizas un componente y luego realizas consultas al DOM resultante a travé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 es la superficie de consulta recomendada. Busca en todo el documento renderizado, lo que refleja cómo un usuario ve la página en lugar de centrarse en un contenedor particular.

Eligiendo la query adecuada

Testing Library ofrece muchas queries, y el orden es importante. Prioriza aquellas que estén más cerca de la perspectiva del usuario:

  1. getByRole — botones, enlaces, encabezados, inputs y más, coincidiendo con el nombre accesible. Esta es la mejor opción por defecto.
  2. getByLabelText — controles de formulario encontrados a través de su etiqueta.
  3. getByPlaceholderText — cuando el placeholder es la única etiqueta disponible.
  4. getByText — contenido de texto no interactivo.
  5. getByDisplayValue — el valor actual de un elemento de formulario.
  6. getByAltText — imágenes mediante su texto alternativo.
  7. getByTitle y getByTestId — como último recurso.
// queries.jsx
screen.getByRole("heading", { level: 1, name: "Dashboard" });
screen.getByLabelText("Password");
screen.getByText("Welcome back");
screen.getByAltText("Company logo");
screen.getByTestId("chart");

getByRole es potente porque también sirve como una comprobación de accesibilidad. Si un control no tiene un nombre accesible, la query falla, lo que significa que es probable que tu markup también sea inaccesible.

Cada query tiene variantes: getBy lanza un error si nada coincide, queryBy devuelve null, y findBy devuelve una promesa que espera. Usa queryBy para asegurar que algo está ausente, y findBy después de una actualización asíncrona.

Interactuando con userEvent

userEvent simula la secuencia completa de eventos que genera un usuario real.

// 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 gestiona los eventos de foco, teclado y puntero de forma conjunta, lo que permite detectar errores que un único fireEvent.change pasaría por alto. Prefiérelo para todo, excepto en los casos excepcionales en los que no cubra la funcionalidad necesaria.

Comportamiento asíncrono

La mayoría de los componentes se actualizan de forma asíncrona, ya sea a través de un fetch, un temporizador o una transición. Utiliza findBy y waitFor en lugar de retardos arbitrarios.

// 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 espera a que aparezca un elemento coincidente y falla con un mensaje útil si nunca aparece. waitFor se utiliza para esperar una aserción o una condición que no sea una simple búsqueda de elementos. Nunca utilices timeouts reales; hacen que las pruebas sean lentas e inestables.

Asserts con jest-dom

El paquete complementario @testing-library/jest-dom añade matchers que se leen de forma natural para el estado del DOM.

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

Estos matchers hacen que la intención sea más clara que las comprobaciones directas de las propiedades del DOM y generan mejores mensajes de error.

Pruebas priorizando la accesibilidad

Dado que getByRole se basa en roles y nombres accesibles, escribir las pruebas de esta manera permite detectar problemas de accesibilidad desde el principio. Si no puedes encontrar un botón por su rol, los usuarios de lectores de pantalla tampoco podrán encontrarlo. Añadir getByRole y toHaveAccessibleName a tus pruebas es una de las formas más económicas de mejorar la accesibilidad y, a menudo, sustituye la necesidad de realizar una auditoría automatizada independiente.

Testing Library en diferentes frameworks

La librería cuenta con adaptadores para React, Vue, Svelte, Angular y otros. La API de consultas es compartida, por lo que el modelo mental se mantiene aunque la configuración varíe. El adaptador de React es el más utilizado y el que se muestra aquí.

Mejores prácticas

  • Realiza las consultas primero por rol, luego por etiqueta y después por texto; utiliza los test ids solo como último recurso.
  • Usa userEvent en lugar de fireEvent.
  • Espera a findBy y waitFor en vez de utilizar retardos (delays).
  • Realiza aserciones sobre lo que el usuario ve, no sobre el estado interno.
  • Mantén los tests enfocados en un solo comportamiento cada uno.
  • Limpia automáticamente entre tests; Testing Library hace esto por defecto.
  • Trata un getByRole fallido como una pista sobre un problema de accesibilidad.

Errores comunes

  • Recurrir a container.querySelector y testear nombres de clases.
  • Usar fireEvent cuando userEvent detectaría más casos.
  • Usar esperas arbitrarias con setTimeout en lugar de findBy.
  • Hacer snapshots de todo el árbol renderizado.
  • Hacer aserciones sobre el estado o las props del componente en lugar del DOM.
  • Añadir test ids a todo y perder los beneficios de la accesibilidad.

Próximos pasos

Testing Library es la capa de componentes de una estrategia de pruebas sólida. Ejecútala con Vitest o Jest, profundiza en tus conocimientos de React para que tus componentes sean testeables y cubre flujos completos con Playwright. Después, toma un componente que ya hayas construido y escribe una prueba desde la perspectiva del usuario.

Encontrar un elemento

Consulta por rol para que la prueba coincida con la forma en que un usuario y la tecnología asistiva encuentran el control, y falle cuando no sea accesible.

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

Simular interacción

userEvent dispara la secuencia completa de eventos que produce un usuario real, incluyendo el foco y el comportamiento del teclado.

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

Preguntas frecuentes

Preguntas frecuentes

Keep learning

Related topics from the roadmap.

$ comienza a aprender

Listo para aprender Testing Library?

Nuestro tutorial interactivo te guia a traves de Testing Library paso a paso — con quizzes y codigo real que puedes ejecutar en el navegador.