Component Testing

Testing Library

Testing Library vous aide à tester vos composants de la même manière qu'un utilisateur les expérimente. Interrogez le DOM par rôle et par texte, interagissez avec des événements réels et arrêtez de tester les détails d'implémentation.

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();
});
Maintenu par
L'équipe Testing Library
Frameworks
React, Vue, Svelte, Angular
Requêtes
Par rôle, label et texte
Événements
userEvent
Async
findBy, waitFor
Philosophie
Tester l'expérience utilisateur

Pourquoi c'est important

Pourquoi Testing Library a changé les tests de composants

Accessible par défaut

L'interrogation par rôle et par nom accessible vous pousse vers un balisage sémantique et compatible avec les lecteurs d'écran.

Résistant aux refactorisations

Les tests qui utilisent la vue utilisateur de la page survivent aux changements internes des composants et de l'état.

Compatible avec tout runner

Testing Library est indépendant du runner, s'associant parfaitement avec Vitest, Jest ou tout autre framework.

Le tableau complet

Les trois piliers de Testing Library

Interrogez le DOM comme les utilisateurs trouvent les éléments, interagissez avec des événements réels et validez ce que l'utilisateur voit.

Requêtes

Trouver

Localisez les éléments par leur rôle, leur label, leur texte ou d'autres attributs visibles par l'utilisateur.

userEvent

Interagir

Simulez des interactions utilisateur réelles telles que la saisie, le clic et la navigation au clavier.

Assertions

Vérifier

Validez ce que l'utilisateur voit, avec les matchers jest-dom pour l'état du DOM.

Testing Library en un coup d'œil

Le cœur de Testing Library

getByRole

La requête privilégiée, correspondant à la manière dont les technologies d'assistance trouvent les éléments.

getByLabelText

Trouvez des contrôles de formulaire par leur label associé, exactement comme le font les utilisateurs.

getByText

Localisez des éléments par leur contenu textuel visible.

userEvent

Déclenchez des événements réalistes incluant le focus, la saisie et les interactions clavier.

findBy et waitFor

Attendez l'apparition d'éléments lorsque les mises à jour sont asynchrones.

Matchers jest-dom

toBeInTheDocument, toHaveTextContent, toBeDisabled et plus encore.

Un bref aperçu

D'Enzyme aux tests centrés sur l'utilisateur

  1. 2018

    React Testing Library

    Kent C. Dodds publie une petite bibliothèque qui teste les composants via le DOM.

    18
  2. 2019

    La famille Testing Library

    Le cœur est extrait et des adaptateurs apparaissent pour Vue, Svelte, Angular et d'autres.

    19
  3. 2021

    Maturation de userEvent

    userEvent devient la méthode recommandée pour simuler les interactions.

    21
  4. 2022

    Dépréciation d'Enzyme

    L'approche basée sur les détails d'implémentation décline et les tests centrés sur l'utilisateur deviennent la norme.

    22
  5. Aujourd'hui

    Le standard

    Testing Library est l'approche par défaut pour le test de composants à travers les frameworks.

    Aujourd'hui

Le guide complet

Testing Library: Tout ce que vous devez savoir

Qu’est-ce que Testing Library ?

Testing Library est une famille de bibliothèques qui vous aident à tester des composants UI de la même manière que l’utilisateur les expérimente. Au lieu de s’appuyer sur les mécanismes internes d’un composant, vous le rendez, vous recherchez les éléments comme le ferait une personne — via leur rôle, leur label ou leur texte visible — et vous interagissez avec eux à travers des événements réalistes.

L’idée centrale est une réaction contre les tests basés sur les détails d’implémentation. Les approches plus anciennes rendaient un composant puis effectuaient des assertions sur l’état interne, les props ou une structure DOM spécifique. Ces tests échouaient à chaque refactorisation tout en détectant très peu de bugs réels. Testing Library inverse la perspective : si l’utilisateur peut le voir et l’utiliser, vous pouvez le tester, et le test survit aux modifications apportées au fonctionnement interne du composant.

Rendu et requêtes

Vous rendez un composant, puis vous interrogez le DOM résultant via 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 est la surface de requête recommandée. Elle recherche dans l’ensemble du document rendu, ce qui reflète la manière dont un utilisateur voit la page plutôt qu’un conteneur spécifique.

Choisir la bonne requête

Testing Library propose de nombreuses requêtes, et l’ordre de priorité est important. Privilégiez celles qui se rapprochent le plus de la perspective de l’utilisateur :

  1. getByRole — boutons, liens, titres, champs de saisie et plus encore, recherchés par leur nom accessible. C’est le meilleur choix par défaut.
  2. getByLabelText — contrôles de formulaire trouvés via leur label.
  3. getByPlaceholderText — lorsque le placeholder est le seul label disponible.
  4. getByText — contenu textuel non interactif.
  5. getByDisplayValue — la valeur actuelle d’un élément de formulaire.
  6. getByAltText — images via leur texte alternatif.
  7. getByTitle et getByTestId — en dernier recours.
// queries.jsx
screen.getByRole("heading", { level: 1, name: "Dashboard" });
screen.getByLabelText("Password");
screen.getByText("Welcome back");
screen.getByAltText("Company logo");
screen.getByTestId("chart");

getByRole est puissant car il fait également office de vérification d’accessibilité. Si un contrôle n’a pas de nom accessible, la requête échoue — ce qui signifie que votre balisage est probablement inaccessible lui aussi.

Chaque requête possède des variantes : getBy lève une erreur si rien ne correspond, queryBy retourne null, et findBy retourne une promesse qui attend la résolution. Utilisez queryBy pour affirmer que quelque chose est absent, et findBy après une mise à jour asynchrone.

Interagir avec userEvent

userEvent simule la séquence complète d’événements générés par un utilisateur réel.

// 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 gère conjointement le focus, le clavier et les événements de pointeur, ce qui permet de détecter des bugs qu’un simple fireEvent.change ne verrait pas. Privilégiez-le pour tout, sauf dans les rares cas où il ne couvre pas vos besoins.

Comportement asynchrone

La plupart des composants se mettent à jour de manière asynchrone, que ce soit suite à un fetch, un timer ou une transition. Utilisez findBy et waitFor plutôt que des délais arbitraires.

// 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 attend qu’un élément correspondant apparaisse et échoue avec un message explicite s’il n’apparaît jamais. waitFor est utilisé pour attendre une assertion ou une condition qui ne correspond pas à une simple recherche d’élément. N’utilisez jamais de timeouts réels ; ils rendent les tests lents et instables.

Assertions avec jest-dom

Le package compagnon @testing-library/jest-dom ajoute des matchers qui permettent de lire naturellement l’état du 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");

Ces matchers rendent l’intention plus claire que les vérifications brutes des propriétés du DOM et produisent de meilleurs messages d’erreur en cas d’échec.

Tests axés sur l’accessibilité

Comme getByRole s’appuie sur les rôles et les noms accessibles, rédiger vos tests de cette manière permet de détecter les problèmes d’accessibilité très tôt. Si vous ne parvenez pas à trouver un bouton par son rôle, les utilisateurs de lecteurs d’écran ne pourront pas le trouver non plus. L’ajout de getByRole et toHaveAccessibleName à vos tests est l’un des moyens les plus simples et les moins coûteux d’améliorer l’accessibilité, et cela remplace souvent la nécessité d’un audit automatisé distinct.

Testing Library à travers les frameworks

La bibliothèque propose des adaptateurs pour React, Vue, Svelte, Angular et d’autres encore. L’API de requête est commune, le modèle mental reste donc le même même si la configuration diffère. L’adaptateur React est le plus utilisé et c’est celui que nous présentons ici.

Bonnes pratiques

  • Effectuez vos requêtes d’abord par rôle, puis par label, puis par texte ; n’utilisez les test ids qu’en dernier recours.
  • Utilisez userEvent au lieu de fireEvent.
  • Attendez findBy et waitFor plutôt que d’utiliser des délais.
  • Effectuez vos assertions sur ce que l’utilisateur voit, et non sur l’état interne.
  • Gardez vos tests focalisés sur un seul comportement chacun.
  • Nettoyez automatiquement entre les tests ; Testing Library le fait par défaut.
  • Considérez l’échec d’un getByRole comme un indice signalant un problème d’accessibilité.

Erreurs courantes

  • Utiliser container.querySelector pour tester les noms de classes.
  • Utiliser fireEvent alors que userEvent permettrait de détecter davantage d’erreurs.
  • Ajouter des attentes setTimeout arbitraires au lieu d’utiliser findBy.
  • Faire des snapshots de l’intégralité de l’arbre rendu.
  • Effectuer des assertions sur l’état ou les props du composant plutôt que sur le DOM.
  • Ajouter des test ids partout et perdre ainsi les bénéfices liés à l’accessibilité.

Et après ?

Testing Library constitue la couche composants d’une stratégie de test solide. Utilisez-la avec Vitest ou Jest, approfondissez vos connaissances en React pour rendre vos composants testables, et couvrez des parcours utilisateurs complets avec Playwright. Pour commencer, prenez un composant que vous avez déjà créé et écrivez un test du point de vue de l’utilisateur.

Trouver un élément

Interrogez par rôle pour que le test corresponde à la façon dont un utilisateur et les technologies d'assistance trouvent le contrôle, et échoue s'il n'est pas accessible.

Préférer
const button = screen.getByRole("button", {
  name: "Save",
});
Éviter
const button = container.querySelector(
  ".btn.btn-primary",
);

Simuler une interaction

userEvent déclenche la séquence complète d'événements produits par un utilisateur réel, incluant le focus et le comportement du clavier.

Préférer
await userEvent.type(
  screen.getByLabelText("Email"),
  "[email protected]",
);
Éviter
fireEvent.change(
  screen.getByLabelText("Email"),
  { target: { value: "[email protected]" } },
);

FAQ

Foire aux questions

Keep learning

Related topics from the roadmap.

$ commencer à apprendre

Prêt à apprendre Testing Library ?

Notre tutoriel interactif vous guide à travers Testing Library pas à pas — avec des quiz et du vrai code que vous pouvez exécuter dans le navigateur.