__CAPGO_KEEP_0__ Startseite

Eine umfassende Anleitung zu Unit-Tests in JavaScript 2026

Meistern Sie JavaScript-Unit-Tests mit unserer 2026-Anleitung. Umfasst Jest, Mocha, Setup, Mocking, CI und Tipps für Capacitor & Electron-Apps.

JavaScript-Unit-Tests: Umfassende 2026-Anleitung

Sie befinden sich wahrscheinlich in einer von zwei Situationen. Entweder Ihr JavaScript-Projekt hat fast keine Tests und jede Refaktorisierung fühlt sich riskant an, oder Sie haben bereits Tests und die Hälfte davon ist langsam, brüchig und schwer zu vertrauen.

Das wird sich in Capacitor und Elektron Apps. Ein einfacher Feature kann gemeinsame Geschäftslogik, Browser-APIs, native Plugins, lokale Dateien, IPC und Remote-Dienste in derselben Fluss berühren. Wenn Sie diese Teile falsch testen, wird Ihr Suite zu einem Labyrinth von fiktiven Abhängigkeiten. Wenn Sie sie richtig testen, erhalten Sie schnelles Feedback auf die Logik, die bricht.

Gute JavaScript-Unit-Tests funktionieren nicht mit cleverem Matcher-Syntax. Sie beginnen mit einer disziplinierten Grenze: Testen Sie reine Logik direkt, isolieren Sie Nebeneffekte und vermeiden Sie es, Tests zu schreiben, die zusammenbrechen, wenn Sie einen internen Funktion umbenennen.

Inhaltsverzeichnis

Die Auswahl Ihres JavaScript-Testframeworks

Ein professionelles JavaScript-Projekt benötigt einen echten Testrunner. Ad-hoc-Skripte und manuelle Konsolenprüfungen skalieren nicht, wenn mehrere Ingenieure an demselben Codebase arbeiten. Sie benötigen Testentdeckung, Behauptungen, asynche Handhabung, Mocks und eine Möglichkeit, alles konsistent in der lokalen Entwicklung und CI auszuführen.

Die aktuelle Leitlinie konvergiert immer wieder auf eine kleine Auswahl an Mainstream-Optionen. Jest, Mocha und Jasmine werden wiederholt als Hauptframeworks hervorgehoben, wobei Jest oft für die integrierte Teststruktur, Behauptungen, Mocks und asynche Unterstützung in einem Paket hervorgehoben wird, wie in diesem Pluralsight-Beitrag zum JavaScript-Testen.

Ein Vergleichsdiagramm, das beliebte JavaScript-Testframeworks einschließlich Jest, Mocha, Cypress und Playwright zeigt.

Warum ein Framework nicht optional ist

Das erste Missverständnis, das Teams haben, ist, dass Einheitstests eine Nebentätigkeit sind. Das führt normalerweise zu inkonsistenten Dateinamen, eigenen Behauptungen, die niemand mehr kennt, und Helfern, die nur einer Person bekannt sind.

A Framework bietet Ihnen eine gemeinsame Sprache:

  • Teststruktur mit describe und test oder it
  • Behauptungen mit lesbaren Vergleichern
  • Hooks für Setup und Teardown
  • Asynksupport für Promise und Timer
  • Mocking-Tools Für externe Abhängigkeiten

Wenn Ihr Team auch einen umfassenderen Überblick über die Automatisierung von Tests benötigt, der über die Einheitsebene hinausgeht, hat Capgo eine nützliche Übersicht. Automatisierte Tests in der Anwendungslieferung.

Jest vs Mocha im Überblick

Jest und Mocha vertreten zwei unterschiedliche Philosophien.

Jest ist die alles-in-einem-Option. Es liefert die meisten benötigten Funktionen bereits am ersten Tag.
Mocha ist modularer. Es liefert einen Runner und erwartet, dass Sie den Rest der Stacks selbst zusammenbauen.

Funktion Jest Mocha
Setup-Komplexität Geringer für die meisten Teams Höher, da Sie normalerweise Assertion- und Mocking-Bibliotheken hinzufügen
Ansprüche gebaut in Usually paired with another library
Mocking gebaut in Usually paired with another library
Asynchrone Tests In der Regel integriert und direkt Unterstützt, aber hängt mehr von der umgebenden Konfiguration ab
Deckungsbeitragsworkflow Zumeist in das gleiche Werkzeugkasten integriert Oftmals eher lose zusammengefügt
Beste Wahl Neue Projekte, Teams, die konsistente Ergebnisse wollen Legacy-Stacks, Teams, die modularen Kontrol haben wollen

Praktische Regel: Wenn Ihr Team fragen muss, welche Assertion-Bibliothek und Mocking-Bibliothek mit dem Runner kombiniert werden sollen, wollen Sie wahrscheinlich Jest.

Was ich für die meisten Teams empfehle

Für die meisten modernen Projekte würde ich Jest es sei denn, das Codebase hat starke Gründe, auf Mocha zu bleiben. Diese Empfehlung wird stärker, wenn die Anwendung auch Capacitor oder Electron, weil diese Projekte bereits genug bewegliche Teile haben. Die Reduzierung des Testwerkzeugschaums zahlt sich schnell aus.

Mocha macht noch immer Sinn in älteren Node.js-Diensten oder langlebigen Codebasen, in denen das umliegende Ökosystem bereits abgesetzt ist. Aber für einen mittelständischen Ingenieur, der von vorneherein eine robuste Suite aufbaut, entfernt Jest in der Regel mehr Hindernisse als es schafft.

Eines wichtigen Umfangsmerkmals. Cypress und Playwright sind hervorragende Werkzeuge, aber sie lösen ein anderes Problem. Sie sind besser für Browser-Ebene- und End-to-End-Überprüfungen geeignet, nicht für die schnelle innere Schleife, in der die Einheitstests JavaScript arbeiten sollten.

Projektsetup und erste Einheitstest

Ein sauberer Testsetup sollte langweilig sein. Wenn die Hinzufügung des ersten Tests kompliziert ist, wird die Suite wahrscheinlich nicht gesund bleiben.

Ein Mann mit Brille, der an einem Programmierprojekt auf einem Laptop an einem Holztisch arbeitet.

Einfache Jest-Einrichtung

Beginnen Sie mit einem JavaScript-Projekt, das bereits eine package.json Dann fügen Sie Jest als Entwicklungsabhängigkeit hinzu und verbinden Sie eine Testskript-Datei.

{
  "scripts": {
    "test": "jest"
  }
}

Das reicht für viele Projekte. Sie können die Konfiguration später erweitern, wenn Ihr Modulsystem, die Transpilation oder die Struktur Ihres Monorepos es erfordert.

Wenn Sie ein Capacitor-Projekt lokal erstellen und Ihre Entwicklungsumgebung vor der Hinzufügung von Tests um die gemeinsame Logik ordnen möchten, ist Capgo's Anleitung zum Einrichten einer Capacitor-Lokalumgebung Schreiben Sie den Test vor der __CAPGO_KEEP_0__

Write the test before the code

Das Test-vor-der-Implementierung-Muster ist nicht nur eine persönliche Vorliebe. Die U.S. Consumer Financial Protection Bureau empfiehlt in ihrer JavaScript-Richtlinie ausdrücklich , organisieren Sie Tests mit, Tests organisieren mit describe and itBehauptungen in ihrer expect(...) JavaScript-Einheitstest-Richtlinie JavaScript-Einheitstest-Leitfaden.

That matters because test-first changes how you design code. Functions tend to become smaller, dependencies become more visible, and side effects stop leaking into logic that should stay pure.

Hier ist ein Minimalbeispiel:

// math.js
function addTax(amount, rate) {
  return amount + amount * rate;
}

module.exports = { addTax };
// math.test.js
const { addTax } = require('./math');

describe('addTax', () => {
  it('returns the amount with the tax applied', () => {
    expect(addTax(100, 0.2)).toBe(120);
  });
});

Verwenden Sie Arrange Act Assert immer

Das Arrange, Akt, Behaupten Muster hält Tests lesbar, selbst wenn sie komplexer werden.

  1. Arrange die Eingabe und jede notwendige Vorbereitung.
  2. Act durch Aufruf der Funktion.
  3. Assert auf dem Ergebnis.

Angewendet auf eine Validierungs-Hilfe:

function isSupportedPlatform(platform) {
  return ['ios', 'android', 'web', 'desktop'].includes(platform);
}

describe('isSupportedPlatform', () => {
  it('returns true for ios', () => {
    // Arrange
    const platform = 'ios';

    // Act
    const result = isSupportedPlatform(platform);

    // Assert
    expect(result).toBe(true);
  });
});

Kleine Tests halten gut. Ein Test sollte normalerweise eine Frage beantworten, nicht eine gesamte Workflow-Abfolge erzählen.

Für Capacitor- und Electron-Projekte ist diese Disziplin noch wichtiger, weil Ihre reine Logik oft neben native oder Desktop-Integrationen code sitzt. Halten Sie die Geschäftsregel ohne die Plattform- Runtime testbar, und Ihr erster Test wird nicht Ihr letzter nützlicher sein.

Meisterung von Mocks und asynchronen Code

Die meisten Fehler in Anwendungen code kommen nicht von der Addition zweier Zahlen. Sie kommen von code , die sich außerhalb selbst befindet: Netzwerk-Anfragen, Dateien, Plugin-APIs, Timer, IPC-Kanäle, Speicherschichten.

Dabei hilft das Mocking. Es gibt dir die Kontrolle über die Grenze, so dass sich der Test auf die Entscheidungsfindung deiner code konzentrieren kann.

Ein weißes Brett-Diagramm, das eine Microservices-Architektur mit APIs, Datenbanken, externen Diensten und eventgetriebenen Datenflüssen illustriert.

Mocken Sie Grenzen, nicht alles

Wartungsfähige Testleitlinien betonen eine-Verhaltensdeckung und eine starke Behauptung pro Test, und es warnt auch davor, dass das Übermäßige von Mocks die Tests brüchig und eng mit Implementierungsdetails gekoppelt macht, wie in diesem Artikel zu wartbaren Einheitstests in TestRail.

Das ist in JavaScript sehr wichtig. Teams beginnen oft damit, jeden importierten Modul zu mocken und landen schließlich bei der Überprüfung, ob Funktionen andere Funktionen in der richtigen Reihenfolge aufrufen, anstatt das echte Verhalten zu testen.

Falsche Zieladresse für einen mock-reichen Test:

  • oben wurde der Hilfsfunktion A aufgerufen
  • oben genannte Dienst C wurde Serializer D aufgerufen
  • ob eine interne private Funktion zweimal aufgerufen wurde

Besseres Ziel:

  • was die Funktion zurückgibt
  • ob sie einen fehlgeschlagenen Abhängigkeit richtig bearbeitet hat
  • ob sie die Daten in die erwartete Form transformiert hat

Eine bessere Muster für Capacitor und Electron code

In mobilen und Desktop-Anwendungen bevorzuge ich eine Wrapper-Schicht um native oder Plattform-APIs herum. Dann mocken die Einheitstests die Wrapper, nicht die Plattform selbst.

Beispielstruktur:

// cameraGateway.js
async function getPhoto(cameraPlugin) {
  return cameraPlugin.getPhoto();
}

module.exports = { getPhoto };
// profilePhotoService.js
async function loadProfilePhoto(cameraGateway) {
  const photo = await cameraGateway.getPhoto();
  return { path: photo.path, ready: true };
}

module.exports = { loadProfilePhoto };
// profilePhotoService.test.js
const { loadProfilePhoto } = require('./profilePhotoService');

test('returns mapped photo data', async () => {
  const fakeCameraGateway = {
    getPhoto: jest.fn().mockResolvedValue({ path: '/tmp/pic.jpg' })
  };

  const result = await loadProfilePhoto(fakeCameraGateway);

  expect(result).toEqual({ path: '/tmp/pic.jpg', ready: true });
});

Dieses Muster funktioniert auch für Electron. Wrap ipcRenderer, Datei-Zugriffe oder Shell-Integrationen hinter einem dünnen Adapter. Die Einheitstests treffen die Dienstschicht, nicht die Laufzeit direkt.

Für Teams, die die Release-Logik und Update-Pfade in Capacitor-Anwendungen testen, hat Capgo eine relevante Anleitung zu dem Testen von Capacitor OTA-Updates mit Mock-Szenarien.

Eine schnelle Anleitung hilft, wenn Ihr Team noch normalisiert, wie man Asynchrone Test-Style schreibt:

Testen von Asynchronen Flüssen ohne Flakiness

Verwende async/await in Tests, wenn der code unter Test eine Promise zurückgibt. Es ist klarer als die callback-reiche Muster und einfacher zu debuggen.

async function fetchProfile(api) {
  const response = await api.getUser();
  return response.name;
}

test('returns the user name from the API response', async () => {
  const api = {
    getUser: jest.fn().mockResolvedValue({ name: 'Ava' })
  };

  const result = await fetchProfile(api);

  expect(result).toBe('Ava');
});

Auch den Fehlerpfad testen:

test('throws when the API request fails', async () => {
  const api = {
    getUser: jest.fn().mockRejectedValue(new Error('network failed'))
  };

  await expect(fetchProfile(api)).rejects.toThrow('network failed');
});

Testen Sie sowohl den glücklichen Weg als auch den unglücklichen Weg. In der Produktion ist der unglückliche Weg meistens der, den die Benutzer merken.

Fortgeschrittene Strategien für Robuste Tests

Eine Test-Suite wird nützlich, wenn sie nach den code Änderungen noch nützlich ist. Das ist schwieriger als die Schreibaufgabe einer Menge von Tests, die laufen.

Eine Diagramm, das Strategien für die Erstellung robuster Software durch umfassende Testabdeckung und wartbare Test-Suiten illustriert.

Nutzen Sie die Test-Splitting als Budget

Eine praktische Anleitung empfiehlt eine 70/20/10 Zuweisung über Einheiten-, Integrations- und End-to-End-Tests, wobei Einheitstests die schnellste Rückmeldung und die stabilsten Fehler liefern. Die gleiche Leitlinie sagt, dass eine vollständige Einheitstest-Suite idealerweise innerhalb von unter 10 Sekunden, and pre-commit checks should stay unter 5 Sekundenbleiben, laut dieser OpenReplay-Testleitfaden.

Das betrachte ich als Budgetwerkzeug, nicht als Religion. Wenn sich die meisten Anstrengungen auf End-to-End-Tests konzentrieren, warten Ihre Teammitglieder zu lange auf Feedback. Wenn alles nur Einheitstests sind, verpassen Sie echte Systemgrenzen.

Für eine Capacitor- oder Electron-Anwendung sieht ein gesunder Balance normalerweise so aus:

  • Einheitstests für Preislogik, Berechtigungsregeln, Serialisierung, Aktualisierungsbedingungen, Feature-Flags und Zustandsänderungen
  • Integrations-Tests zur Speicherverwaltung, zu Plugin-Wrappern und zu IPC-Verträgen
  • E2E-Tests zur Überprüfung von wenigen kritischen Reiseverläufen wie Login, Kaufablauf, Synchronisierung oder Update-Anfragen

Deckungsgrad ist ein Taschenlampenlicht, kein Ziel

Deckungsgrad-Berichte sind nützlich, wenn sie Ihnen helfen, ungetestete Zweige in wichtigen Logiken zu erkennen. Sie werden schädlich, wenn Teams Deckungsgrad-Prozentsätze für ihren eigenen Willen verfolgen.

Ein Login-Validator mit sorgfältigen Ausnahmefall-Tests liefert mehr Wert als ein abgedeckter Dateiinhalt mit trivialen Behauptungen. Das ist besonders wahr für Eingabeintensiven code wie Formulare, Parser, Datumlogik und Berechtigungsprüfungen. Wenn Ihr Team die Qualität um die Validierung-intensiven UI herum verschärft, ist diese Anleitung auf Vervollkommung der Frontend-Formularvalidierung ist ein gutes Pendant zur Strategie der Einheitstests.

Verhaltens-basierte Tests überstehen Refaktorisierungen

Ein zuverlässiges Suite sollte es dir ermöglichen, interne Strukturen ohne die Hälfte der Tests neu zu schreiben. Die einfachste Möglichkeit, dorthin zu gelangen, ist, zu behaupten beobachtbares Verhalten statt Implementierungsdetails.

Verwendungsfälle, die gut halten:

  • Boundary conditions wie leerer Eingabewert, nullartige Werte, ungültige Typen und überdimensionierte Zeichenketten
  • Domänenergebnisse wie z.B. „Zugriffsverweigerung bei fehlender Berechtigung“
  • Zustandsübergänge z.B. ‘markt als ausstehend nach dem Download von Metadaten validiert’

Anwendungsfälle, die oft verrotten:

  • Internen Hilfsfunktionen untersuchen
  • Private Methodenfolgen behaupten
  • Jeden Schicht in der Aufrufkette mocken

Für App-Teams, die disziplinierte Release-Prozesse aufbauen, ist der Artikel von Capgo Testen für CI, __CAPGO_KEEP_0__, und Electron-Apps Es ist nützlich, weil es die Testarbeit mit der breiteren Release-Pipeline verbindet.

Testing für CI, Capacitor, und Electron-Apps

Ein Test, der nur auf einem Entwickler-Computer läuft, ist kein Sicherheitsnetz. Er ist eine lokale Gewohnheit.

CI turns unit tests JavaScript work into team infrastructure. Every push, pull request, or release branch can exercise the same commands with the same expectations. That consistency matters even more for Capacitor and Electron projects, where environment drift causes subtle failures.

CI als Standardausführungspfad machen

Mindestens sollte Ihre CI-Instanz Abhängigkeiten installieren und die Einheitstest-Suite auf jedem Änderungssatz ausführen. Halten Sie den Befehl, wenn möglich, identisch zur lokalen Entwicklung.

Ein grundlegender GitHub Actions-Workflow kann so klein wie folgt sein:

name: test

on: [push, pull_request]

jobs:
  unit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm test

Das reicht aus, um fehlerhafte Importe, fehlgeschlagene Anforderungen und versehentliche Plattformannahmen vor der Veröffentlichung in der Hauptversion zu erkennen.

Für mobile Teams, die über automatisierte Pipelines liefern, hat Capgo eine praktische Anleitung Einrichtung von CI/CD für Capacitor-Anwendungen.

Testen Sie die Interaktionen des Capacitor-Plugins.

The wrong way to unit test Capacitor code is to pull native plugins directly into every service. That couples your test suite to the platform bridge.

Die bessere Muster ist eine dünne Abstraktion:

// deviceStorage.js
async function saveFile(filesystem, path, data) {
  return filesystem.writeFile({ path, data });
}

module.exports = { saveFile };
// draftService.js
async function persistDraft(storage, draft) {
  await storage.save('draft.json', JSON.stringify(draft));
  return { saved: true };
}

module.exports = { persistDraft };
// draftService.test.js
const { persistDraft } = require('./draftService');

test('persists a serialized draft', async () => {
  const storage = {
    save: jest.fn().mockResolvedValue(undefined)
  };

  const result = await persistDraft(storage, { title: 'Hello' });

  expect(result).toEqual({ saved: true });
});

The same idea applies to camera access, biometric prompts, push-token registration, and network status. Keep plugin calls in adapters. Test app logic against interfaces you control.

Testen Sie Electron-Hauptrenderer und IPC code

Elektron-Apps haben zwei wichtige Schnittstellen. Hauptprozess code und renderer Prozess code. Blenden Sie sie in Tests nicht.

Ein zuverlässiger Aufbau trennt normalerweise:

  • Renderer-Einheitstests für View-Modelle, Zustände, Formatierungen und Geschäftslogik auf der Benutzeroberfläche
  • Hauptprozess-Einheitstests für Menüs, Dateibearbeitungen und Lebenszyklusentscheidungen
  • IPC-Vertragsprüfungen für Nachrichtenform und erwartete Antworten

Beispiel für eine IPC-Hülle:

// ipcGateway.js
function sendSettings(ipcRenderer, payload) {
  ipcRenderer.send('settings:update', payload);
}

module.exports = { sendSettings };
// ipcGateway.test.js
const { sendSettings } = require('./ipcGateway');

test('sends settings update over ipc', () => {
  const ipcRenderer = { send: jest.fn() };

  sendSettings(ipcRenderer, { theme: 'dark' });

  expect(ipcRenderer.send).toHaveBeenCalledWith('settings:update', { theme: 'dark' });
});

Wenn Sie die interne Implementierung später von einer Hilfsmethode in eine andere ändern, hält sich dieser Test noch immer, da er die verhaltensrelevanten Aspekte überprüft. Das ist der Standard, den Sie auf Desktop- und Mobilgeräten erreichen möchten code.

Häufig gestellte Fragen zu JavaScript-Einheitstests

Was ist der Unterschied zwischen Einheitstests, Integrations- und E2E-Tests

A Ein Einheitstest prüft einen kleinen Teil der Logik in Isolation. Ein Integrations-Test prüft, ob einige Komponenten oder Dienste korrekt zusammenarbeiten. Ein End-to-End-Test übt eine Benutzerreise durch die laufende Anwendung aus.

Verwenden Sie Einheitstests für schnelles Vertrauen in Geschäftsregeln. Verwenden Sie Integrations-Tests für Scharniere wie Speicher, Plugin-Wrapper und IPC. Verwenden Sie E2E-Tests sparsam für die Workflows, die ernsthafte Schäden verursachen würden, wenn sie fehlschlagen.

Sollten wir uns für eine vollständige Abdeckung richten

Nein. Eine vollständige Abdeckung kann Teams zu Tests mit niedrigem Wert treiben.

Abdeckung ist nützlich, wenn sie gefährliche code offenlegt, die niemand ausprobiert hat. Sie ist nicht nützlich, wenn Ingenieure nur, um die Anzeige zu erfüllen, flache Behauptungen hinzufügen.

Wie fügen wir Tests zu einem bestehenden Codebase hinzu?

Beginne dort, wo Änderungen bereits stattfinden. Ersticke das Team nicht und verkünde eine umfassende Überarbeitung der Teststrategie.

Ein praktischer Ablauf sieht wie folgt aus:

  • Schützen Sie aktive code zuerst indem Sie Tests zu Modulen hinzufügen, die Sie während der Feature-Arbeit oder bei Bug-Fixes berühren
  • Entfernen Sie reine Logik aus schwer zu testenden Dateien, damit Geschäftsregeln ohne Framework- oder Laufzeit-Rauschen getestet werden können
  • Fügen Sie Schaltschalter hinzu um native Plugins, Netzwerkclients, Dateisystemaufrufe und Electron-IPC umzugehen
  • Weigern Sie sich, brüchige Muster wenn Sie Mocks einführen. Anleitung von JavaScript-Test-Praktiken ist hier besonders nützlich, da es das oft übersehene Problem der Über-Mockung und die brüchigen Tests, die folgen, hervorhebt

Das Ziel ist nicht sofortige Vollständigkeit, sondern ein kontinuierlicher Fortschritt in den Bereichen, in denen Rückschritte dem Team am meisten Kosten.


Wenn Ihr Team versendet Capacitor Elektron Electron Anwendungen und benötigt einen sauberen Release-Prozess für JavaScript-Änderungen. Capgo is one option to look at. It provides live updates for CapacitorJS and Electron apps, with rollout controls and observability, so teams can pair solid unit testing with a safer path to shipping web bundle changes without waiting on store review for every fix.

Live-Updates für Capacitor-Anwendungen

Wenn ein Web-Schicht-Bug live ist, liefern Sie die Reparatur über Capgo anstatt Tage zu warten, bis die App-Store-Zulassung vorliegt. Die Benutzer erhalten die Aktualisierung im Hintergrund, während native Änderungen im normalen Review-Prozess bleiben.

Neuestes von unserem Blog

Capgo bietet Ihnen die besten Einblicke, die Sie benötigen, um eine wirklich professionelle mobile App zu erstellen.