Test Runner

Jest

Jest est le runner de tests JavaScript classique : complet, capable de gérer les snapshots et toujours le choix par défaut dans d'innombrables bases de code Node.js et React.

intermediate13 min readUpdated 15 sept. 2026
sum.test.js
js
// sum.test.js
import { sum } from "./sum";

describe("sum", () => {
  test("adds two numbers", () => {
    expect(sum(2, 3)).toBe(5);
  });

  test("handles negatives", () => {
    expect(sum(-1, -1)).toBe(-2);
  });
});
Maintenu par
Meta
API
describe, test, expect
Mocks
jest.fn, jest.mock
Snapshots
Intégrés
Couverture
Intégrée
Transforms
Babel, ts-jest, SWC

Pourquoi c'est important

Pourquoi Jest est toujours pertinent

Batteries included

Assertions, mocking, snapshots et couverture sont livrés ensemble, donc un nouveau projet nécessite très peu de configuration.

Snapshots

Capturez une sortie une seule fois et détectez les changements involontaires, très utile pour les structures sérialisables volumineuses.

Écosystème mature

Des années de plugins, de presets et d'intégrations signifient que presque n'importe quelle stack possède une configuration Jest documentée.

Le tableau complet

Les trois piliers de Jest

Un runner sans configuration, une API d'assertion familière et des fonctionnalités intégrées de mocking, de snapshots et de couverture.

Le runner

Exécuter

Découvre les fichiers de test, les exécute dans des environnements isolés et rapporte les résultats.

Assertions et mocks

Vérifier

expect avec des matchers, plus jest.fn, jest.spyOn et jest.mock pour l'isolation.

Pipeline de transformation

Construire

Babel, ts-jest ou SWC compilent la syntaxe moderne et le JSX avant l'exécution des tests.

Jest en un coup d'œil

Le cœur de Jest

describe et test

Groupez les suites de tests et déclarez les cas individuels par comportement.

Matchers

toBe, toEqual, toMatchObject, toThrow et bien d'autres.

Mocks et spies

jest.fn, jest.spyOn et jest.mock isolent l'unité sous test.

Fake timers

Contrôlez setTimeout et Date pour des tests de timing déterministes.

Snapshots

Stockez un résultat sérialisé et comparez-le lors des exécutions suivantes.

Couverture

Rapports de couverture intégrés avec définition de seuils.

Un bref aperçu

Le runner qui a défini une génération

  1. 2014

    Sortie de Jest

    Facebook introduit un runner de tests conçu pour les projets React et JavaScript.

    14
  2. 2016

    Jest 15 et 16

    Une réécriture réduit les frictions de configuration et les tests par snapshot se généralisent.

    16
  3. 2018

    Jest 23 et au-delà

    Jest devient le runner de tests JavaScript le plus largement utilisé.

    18
  4. 2021

    L'ascension de Vite et Vitest

    Vitest offre une alternative plus rapide, native à Vite, avec une API compatible.

    21
  5. Aujourd'hui

    Toujours omniprésent

    Dominant dans les bases de code Node.js, React et React Native existantes, et pleinement maintenu.

    Aujourd'hui

Le guide complet

Jest: Tout ce que vous devez savoir

Qu’est-ce que Jest ?

Jest est un test runner JavaScript créé par Facebook, devenu aujourd’hui l’un des outils de test les plus utilisés de l’écosystème. Il est batteries-included : les assertions, le mocking, le snapshot testing et la couverture de code sont tous inclus dans un seul package, et un nouveau projet nécessite très peu de configuration pour démarrer.

Pendant des années, Jest a été le choix par défaut pour les projets React et Node.js, et il reste dominant dans les bases de code existantes. Même avec la montée en puissance de Vitest, l’API de Jest constitue le vocabulaire commun des tests JavaScript, ce qui rend son apprentissage indispensable, quel que soit le runner que vous utilisez au quotidien.

Écrire des tests

Un fichier de test Jest utilise describe pour grouper et test (ou it) pour déclarer un cas de test.

// cart.test.js
import { Cart } from "./cart";

describe("Cart", () => {
  test("starts empty", () => {
    expect(new Cart().items).toEqual([]);
  });

  test("adds an item", () => {
    const cart = new Cart();
    cart.add({ id: 1, price: 10 });
    expect(cart.items).toHaveLength(1);
  });
});

Utilisez beforeEach et afterEach pour la configuration et le nettoyage (setup/teardown), et beforeAll et afterAll lorsqu’une ressource doit être créée une seule fois pour l’ensemble du fichier. Nommez vos tests en fonction du comportement attendu afin qu’un échec vous indique précisément ce qui ne fonctionne plus.

Matchers

L’API expect de Jest est vaste et expressive.

// matchers.test.js
expect(value).toBe(5);                 // strict equality
expect(value).toEqual({ a: 1 });       // deep equality
expect(value).toBeDefined();
expect(list).toContain("a");
expect(fn).toThrow("invalid");
expect(value).toBeGreaterThan(3);
expect(obj).toMatchObject({ id: 1 });  // partial match

toBe compare avec Object.is et convient parfaitement aux types primitifs. toEqual compare récursivement les objets et les tableaux. toStrictEqual est plus strict concernant les types et les propriétés undefined. toMatchObject est utile lorsque vous ne vous intéressez qu’à un sous-ensemble d’une structure.

Mocks, spies et mocking de modules

Le système de mocking de Jest est l’une de ses fonctionnalités les plus puissantes.

// users.test.js
import { jest } from "@jest/globals";
import { getUser } from "./users";

jest.mock("./http", () => ({
  get: jest.fn().mockResolvedValue({ id: 1, name: "Ada" }),
}));

test("returns a user", async () => {
  await expect(getUser(1)).resolves.toEqual({ id: 1, name: "Ada" });
});

jest.fn crée une fonction mock, jest.spyOn enveloppe une méthode réelle pour vous permettre d’observer les appels et de la restaurer plus tard, et jest.mock remplace un module. Comme jest.mock est “hoisted” (hissé) au-dessus des imports, le mock est en place avant le chargement du module testé.

Réinitialisez toujours vos mocks entre chaque test. Activez clearMocks, resetMocks ou restoreMocks dans la configuration, ou appelez l’assistant ...AllMocks correspondant dans afterEach. Un état de mock qui persiste d’un test à l’autre est l’une des raisons les plus courantes pour lesquelles des tests réussissent individuellement mais échouent lorsqu’ils sont lancés ensemble.

Tests asynchrones

Utilisez async/await avec resolves et rejects, exactement comme vous le feriez dans Vitest.

// async.test.js
test("rejects on failure", async () => {
  await expect(loadUser(-1)).rejects.toThrow("Invalid id");
});

Le callback done fonctionne, mais il est facile de faire des erreurs. Privilégiez l’utilisation de await. Pour les timers, jest.useFakeTimers() combiné à jest.advanceTimersByTime() permet de rendre les tests de debounce et de retry déterministes.

Snapshots

Les snapshots sérialisent une valeur et la comparent lors des exécutions futures.

// config.test.js
test("builds the default config", () => {
  expect(createConfig({ debug: true })).toMatchInlineSnapshot();
});

Les snapshots inline résident dans le fichier de test, ce qui permet de les examiner via un diff. Les snapshots externes sont pratiques pour les sorties volumineuses, mais elles sont fréquemment mises à jour sans inspection, ce qui en fait une simple formalité. Utilisez les snapshots pour des données sérialisables stables, et non comme un substitut à une réflexion sur les points essentiels.

Configuration

Jest lit sa configuration depuis jest.config.js, une clé jest dans package.json ou un flag CLI.

// jest.config.js
export default {
  testEnvironment: "jsdom",
  clearMocks: true,
  collectCoverage: true,
  coverageThreshold: {
    global: { lines: 80, functions: 80 },
  },
  transform: {
    "^.+\\.(t|j)sx?$": ["@swc/jest"],
  },
};

testEnvironment permet de choisir entre node ou jsdom. clearMocks empêche les fuites de mémoire. Les seuils de couverture (coverage thresholds) transforment un objectif en une règle contraignante. Le transform détermine comment TypeScript et JSX sont compilés, avec ts-jest, Babel et SWC comme options courantes.

Où se place Jest

Jest constitue la couche de tests unitaires et d’intégration. Pour le comportement des composants, associez-le à Testing Library afin de tester du point de vue de l’utilisateur. Pour les flux utilisateurs complets, utilisez un outil de bout en bout tel que Playwright ou Cypress. Si vous lancez un nouveau projet Vite, Vitest propose la même API avec un pipeline partagé plus rapide.

Bonnes pratiques

  • Testez le comportement via les API publiques, et non via les mécanismes internes privés.
  • Maintenez une seule assertion logique par test, lorsque cela est possible.
  • Réinitialisez et restaurez les mocks entre chaque test.
  • Privilégiez async/await à done.
  • Utilisez des fake timers pour tout ce qui dépend du temps.
  • Effectuez des snapshots de structures petites et stables, et examinez chaque mise à jour.
  • Exécutez les tests en CI à chaque modification, et pas seulement localement.

Erreurs courantes

  • Faire des assertions sur des détails d’implémentation, ce qui casse les tests lors des refactorisations.
  • Mettre à jour les snapshots sans vérification.
  • Oublier de réinitialiser les mocks, entraînant des fuites d’état entre les tests.
  • Utiliser des timers réels, rendant les tests lents ou instables (flaky).
  • Tout tester au niveau unitaire et passer à côté de bugs d’intégration.
  • Ignorer la couverture de code tout en supposant que les tests couvrent les chemins critiques.

Et après ?

Jest constitue une base solide et un vocabulaire commun à travers tout l’écosystème. Comparez-le avec Vitest pour vos projets Vite modernes, ajoutez Testing Library pour vos composants, et couvrez vos parcours utilisateurs avec Playwright ou Cypress. Ensuite, écrivez un test pour un bug que vous avez récemment corrigé afin de vous protéger contre les régressions.

Tester du code asynchrone

Attendez la promesse avec await et affirmez le résultat. Le callback done est facile à oublier et provoque des timeouts confus.

Préférer
test("loads the user", async () => {
  await expect(getUser(1)).resolves.toEqual({
    id: 1,
    name: "Ada",
  });
});
Éviter
test("loads the user", (done) => {
  getUser(1).then((user) => {
    expect(user.name).toBe("Ada");
    done();
  });
});

Portée des snapshots

Faites des snapshots de structures petites et stables. Un snapshot énorme que tout le monde met à jour aveuglément est pire que l'absence de test.

Préférer
expect(parseConfig(input)).toMatchInlineSnapshot(`
  {
    "debug": true,
    "level": "info",
  }
`);
Éviter
expect(renderWholeApp()).toMatchSnapshot();
// huge, unstable and always
// updated without review

FAQ

Foire aux questions

Keep learning

Related topics from the roadmap.

$ commencer à apprendre

Prêt à apprendre Jest ?

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