Test Runner

Jest

Jest ist der klassische JavaScript Test Runner: batteries-included, snapshot-fähig und nach wie vor der Standard in zahllosen Node und React Codebases.

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);
  });
});
Gewartet von
Meta
API
describe, test, expect
Mocks
jest.fn, jest.mock
Snapshots
Integriert
Coverage
Integriert
Transforms
Babel, ts-jest, SWC

Warum es wichtig ist

Warum Jest immer noch wichtig ist

Batteries included

Assertions, Mocking, Snapshots und Coverage sind bereits enthalten, sodass ein neues Projekt kaum Setup benötigt.

Snapshots

Einmalig den Output erfassen und unbeabsichtigte Änderungen erkennen – besonders nützlich für große serialisierbare Strukturen.

Reifes Ökosystem

Jahre voller Plugins, Presets und Integrationen bedeuten, dass fast jeder Stack ein dokumentiertes Jest-Setup besitzt.

Das Gesamtbild

Die drei Kernideen hinter Jest

Ein Zero-Config Runner, eine vertraute Assertion API sowie integrierte Mocks, Snapshots und Coverage.

Der Runner

Ausführen

Findet Testdateien, führt sie in isolierten Umgebungen aus und berichtet die Ergebnisse.

Assertions und Mocks

Verifizieren

expect mit Matchern, sowie jest.fn, jest.spyOn und jest.mock zur Isolation.

Transform Pipeline

Build

Babel, ts-jest oder SWC kompilieren moderne Syntax und JSX, bevor die Tests laufen.

Jest auf einen Blick

Der Kern von Jest

describe und test

Gruppiere Test-Suites und definiere einzelne Testfälle nach ihrem Verhalten.

Matcher

toBe, toEqual, toMatchObject, toThrow und viele mehr.

Mocks und Spies

jest.fn, jest.spyOn und jest.mock isolieren die zu testende Einheit.

Fake Timers

Steuere setTimeout und Date für deterministische Timing-Tests.

Snapshots

Speichere ein serialisiertes Ergebnis und vergleiche es bei späteren Durchläufen.

Coverage

Integriertes Coverage-Reporting mit definierten Schwellenwerten.

Eine kurze Geschichte

Der Runner, der eine Generation prägte

  1. 2014

    Jest Release

    Facebook stellt einen Test Runner vor, der speziell für React und JavaScript Projekte entwickelt wurde.

    14
  2. 2016

    Jest 15 und 16

    Ein Rewrite reduziert den Konfigurationsaufwand und Snapshot-Testing wird zum Mainstream.

    16
  3. 2018

    Jest 23 und darüber hinaus

    Jest wird zum am weitesten verbreiteten JavaScript Test Runner.

    18
  4. 2021

    Aufstieg von Vite und Vitest

    Vitest bietet eine schnellere, Vite-native Alternative mit einer kompatiblen API.

    21
  5. Heute

    Immer noch allgegenwärtig

    Dominant in bestehenden Node, React und React Native Codebases und vollständig gewartet.

    Heute

Der vollständige Leitfaden

Jest: Alles was Sie wissen müssen

Was ist Jest?

Jest ist ein JavaScript Test-Runner, der bei Facebook entwickelt wurde und mittlerweile eines der am weitesten verbreiteten Testing-Tools im Ökosystem ist. Es ist „batteries-included“: Assertions, Mocking, Snapshot-Testing und Coverage sind alle in einem Paket enthalten, sodass ein neues Projekt nur sehr wenig Konfiguration benötigt, um startklar zu sein.

Jahrelang war Jest die Standardwahl für React- und Node-Projekte und ist in bestehenden Codebases nach wie vor dominant. Selbst angesichts des Aufstiegs von Vitest ist die API von Jest das gemeinsame Vokabular des JavaScript-Testings. Das macht es lohnenswert, Jest zu kennen, unabhängig davon, welchen Runner man im Alltag verwendet.

Tests schreiben

Eine Jest-Testdatei verwendet describe zur Gruppierung und test (oder it), um einen Testfall zu deklarieren.

// 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);
  });
});

Nutze beforeEach und afterEach für Setup und Teardown sowie beforeAll und afterAll, wenn eine Ressource einmalig für die gesamte Datei erstellt werden soll. Benenne Tests nach ihrem Verhalten, damit ein Fehler direkt verrät, was genau kaputtgegangen ist.

Matchers

Die expect API von Jest ist umfangreich und ausdrucksstark.

// 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 vergleicht Werte mit Object.is und eignet sich für Primitive. toEqual vergleicht Objekte und Arrays rekursiv. toStrictEqual ist strenger bei Typen und undefined Properties. toMatchObject ist nützlich, wenn Sie sich nur für eine Teilmenge einer Struktur interessieren.

Mocks, Spies und Module Mocking

Das Mocking in Jest ist eines seiner stärksten Features.

// 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 erstellt eine Mock-Funktion, jest.spyOn umschließt eine echte Methode, sodass Sie Aufrufe beobachten und diese später wiederherstellen können, und jest.mock ersetzt ein Modul. Da jest.mock über die Imports gehoben (hoisted) wird, ist der Mock bereits aktiv, bevor das zu testende Modul geladen wird.

Setzen Sie Mocks zwischen den Tests immer zurück. Aktivieren Sie clearMocks, resetMocks oder restoreMocks in der Konfiguration oder rufen Sie den entsprechenden ...AllMocks-Helper in afterEach auf. Ein überbleibender Mock-Status ist einer der häufigsten Gründe, warum Tests einzeln bestehen, aber gemeinsam fehlschlagen.

Asynchrones Testen

Verwenden Sie async/await zusammen mit resolves und rejects, genau so, wie Sie es in Vitest tun würden.

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

Der done-Callback funktioniert zwar, ist aber anfällig für Fehler. Bevorzugen Sie await. Für Timer machen jest.useFakeTimers() in Kombination mit jest.advanceTimersByTime() Tests für Debounce und Retry deterministisch.

Snapshots

Snapshots serialisieren einen Wert und vergleichen diesen bei zukünftigen Durchläufen.

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

Inline-Snapshots befinden sich direkt in der Testdatei, wodurch sie in einem Diff einfach überprüfbar sind. Externe Snapshots sind bei großen Ausgaben praktisch, werden aber häufig ohne genaue Prüfung aktualisiert, was sie zu einer bloßen Formsache macht. Nutzen Sie Snapshots für stabile, serialisierbare Daten und nicht als Ersatz dafür, sich Gedanken darüber zu machen, was wirklich wichtig ist.

Konfiguration

Jest liest die Konfiguration aus jest.config.js, einem jest-Key in package.json oder einem CLI-Flag.

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

testEnvironment wählt zwischen node oder jsdom. clearMocks verhindert Leakage. Coverage-Thresholds machen aus einem Ziel eine verbindliche Regel. Der Transform legt fest, wie TypeScript und JSX kompiliert werden, wobei ts-jest, Babel und SWC die gängigen Optionen sind.

Wo Jest ins Spiel kommt

Jest bildet die Ebene für Unit- und Integrationstests. Um das Verhalten von Komponenten aus der Perspektive des Nutzers zu testen, kombiniere es mit Testing Library. Für vollständige User-Flows solltest du ein End-to-End-Tool wie Playwright oder Cypress verwenden. Wenn du ein neues Vite-Projekt startest, bietet Vitest dieselbe API mit einer schnelleren, gemeinsamen Pipeline.

Best Practices

  • Testen Sie das Verhalten über öffentliche APIs, nicht über private Internals.
  • Behalten Sie, sofern praktikabel, eine logische Assertion pro Test bei.
  • Setzen Sie Mocks zwischen den Tests zurück und stellen Sie sie wieder her.
  • Bevorzugen Sie async/await gegenüber done.
  • Verwenden Sie Fake Timer für alles, was zeitabhängig ist.
  • Erstellen Sie Snapshots von kleinen, stabilen Strukturen und prüfen Sie jedes Update.
  • Führen Sie Tests bei jeder Änderung in der CI aus, nicht nur lokal.

Häufige Fehler

  • Assertions auf Implementierungsdetails, wodurch Tests bei Refactors fehlschlagen.
  • Blindes Aktualisieren von Snapshots.
  • Vergessen, Mocks zu leeren, was zu State-Leaks zwischen den Tests führt.
  • Verwendung von echten Timern, was Tests langsam oder flaky macht.
  • Alles auf Unit-Level testen und dadurch Integrationsfehler übersehen.
  • Die Coverage ignorieren, während man fälschlicherweise annimmt, dass die Tests die wichtigen Pfade abdecken.

Wie geht es weiter?

Jest bietet ein zuverlässiges Fundament und eine gemeinsame Sprache innerhalb des gesamten Ökosystems. Vergleiche es mit Vitest für moderne Vite-Projekte, ergänze Testing Library für Komponenten und decke User Journeys mit Playwright oder Cypress ab. Schreibe anschließend einen Test für einen Bug, den du kürzlich behoben hast, damit dieser dich vor Regressionen schützt.

Asynchronen Code testen

Warte auf das Promise und prüfe das Ergebnis. Der done-Callback wird leicht vergessen und führt zu verwirrenden Timeouts.

Bevorzugt
test("loads the user", async () => {
  await expect(getUser(1)).resolves.toEqual({
    id: 1,
    name: "Ada",
  });
});
Vermeiden
test("loads the user", (done) => {
  getUser(1).then((user) => {
    expect(user.name).toBe("Ada");
    done();
  });
});

Snapshot-Scope

Erstelle Snapshots von kleinen, stabilen Strukturen. Ein riesiger Snapshot, den jeder blind aktualisiert, ist schlimmer als gar kein Test.

Bevorzugt
expect(parseConfig(input)).toMatchInlineSnapshot(`
  {
    "debug": true,
    "level": "info",
  }
`);
Vermeiden
expect(renderWholeApp()).toMatchSnapshot();
// huge, unstable and always
// updated without review

Häufig gestellte Fragen

Häufig gestellte Fragen

Keep learning

Related topics from the roadmap.

$ Lernen Sie jetzt

Bereit, Jest zu lernen?

Unser interaktives Tutorial führt Sie Schritt für Schritt durch Jest — mit Quizzen und echtem Code, den Sie im Browser ausführen können.