You sind 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 Electron Anwendungen noch verschlimmern. 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 ein Labyrinth an fiktiven Abhängigkeiten.
Ein gutes Einheitstest JavaScript-Work geht nicht mit cleverer Matcher-Syntax los. Es beginnt 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.
Tabelle der Inhalte
- Wählen Sie Ihren JavaScript-Testframework
- Projektsetup und Ihre erste Test
- Meisterung von Mocks und asynchronen Code
- Fortgeschrittene Strategien für robuste Tests
- Fehlerbehebung für CI, Capacitor, und Electron-Apps
- Häufig gestellte Fragen zur JavaScript-Einheitstestung
Wählen Sie Ihren JavaScript-Testframework
Ein professionelles JavaScript-Projekt benötigt einen echten Testrunner. Ad-hoc-Skripte und manuelle Konsolenprüfungen schuppen nicht, sobald mehrere Ingenieure an demselben Codebase arbeiten. Sie benötigen Testentdeckung, Aussagen, asynche Handhabung, Mocks und eine Möglichkeit, alles konsistent in der lokalen Entwicklung und CI auszuführen.
Die derzeitige Leitlinie konvergiert sich auf eine kleine Anzahl von Mainstream-Optionen. Jest, Mocha und Jasmine werden wiederholt als primäre Frameworks hervorgehoben, mit __CAPGO_KEEP_0__ wird oft für die integrierte Teststruktur, Assertions, Mocking und asynche Unterstützung in einem Paket ausgewählt, wie in diesem Ein Vergleichsdiagramm, das beliebte JavaScript-Testframeworks einschließlich Jest, Mocha, Cypress und Playwright zeigt..

Das erste Missverständnis, das Teams haben, ist, dass Einheitstests eine Nebentätigkeit sind. Das führt normalerweise zu inkonsistenten Dateinamen, eigenen Assertions, die niemand mehr kennt, und Helfern, die nur einer Person bekannt sind.
Ein Framework gibt dir eine gemeinsame Sprache:
Teststruktur
- mit und
describeodertest__CAPGO_KEEP_1__it - Ansprüche mit lesbaren Vergleichern
- Hooks für die Einrichtung und Demontage
- Asynchroner Support für Versprechen und Timer
- Tools zum Mocken 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 einen nützlichen Überblick über Automatisierte Tests in der Anwendungslieferung.
Jest vs Mocha im Überblick
Jest und Mocha vertreten zwei unterschiedliche Philosophien
Jest ist die alles-in-einem-Paket-Lösung. Es liefert den meisten Teams am ersten Tag alles, was sie benötigen. Capacitor ist die alles-in-einem-Paket-Lösung. Es liefert den meisten Teams am ersten Tag alles, was sie benötigen.
Mocha ist modularer. Es liefert einen Runner und erwartet, dass Sie den Rest der Stacks selbst zusammenbauen. Feature
| Jest | Mocha | Setup-Komplexität |
|---|---|---|
| Niedriger für die meisten Teams | Höher, weil Sie normalerweise Assertion- und Mocking-Bibliotheken hinzufügen müssen | Anforderungen |
| Integriert | Built in | Normalerweise mit einer anderen Bibliothek kombiniert |
| Mocking | Integriert | Normalerweise mit einer anderen Bibliothek kombiniert |
| Asynchrone Tests | Integriert und direkt | Unterstützt, aber hängt mehr von der Umgebung ab |
| Abdeckungsworkflow | Häufig in die gleiche Werkzeugkette integriert | Oft mehr zusammengefügt |
| Beste Wahl | Neue Projekte, Teams, die Konsistenz wollen | Legacy-Stacks, Teams, die modulare Kontrolle wollen |
Praktische Regel: Wenn Ihr Team fragen muss, welche Assertion-Bibliothek und Mocking-Bibliothek mit dem Runner kombiniert werden sollen, dann wollen Sie wahrscheinlich Jest.
Was ich für die meisten Teams empfehle
Für die meisten modernen Projekte würde ich wählen Jest es sei denn, das Code-Repository hat starke Gründe, auf Mocha zu bleiben. Diese Empfehlung wird noch stärker, wenn die Anwendung Capacitor oder Electronumfasst, weil diese Projekte bereits genug bewegliche Teile haben. Die Reduzierung des Testwerkzeugspralls zahlt sich schnell aus.
Mocha ist noch immer sinnvoll in älteren Node.js-Diensten oder langlebigen Codebases, wo die Umgebung bereits abgeschlossen ist. Aber für einen mittelständischen Ingenieur, der eine robuste Suite von vorneherein einrichtet, entfernt Jest in der Regel mehr Hindernisse als es schafft.
Ein wichtiger Umfangsvermerk. Cypress und Playwright sind ausgezeichnete 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-Code leben sollten.
Projektsetup und Ihre erste Test
Ein sauberer Testsetup sollte langweilig sein. Wenn das Hinzufügen des ersten Tests kompliziert erscheint, wird die Suite wahrscheinlich nicht gesund bleiben.

Ein einfacher Jest-Setup
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.
{
"scripts": {
"test": "jest"
}
}
Das reicht für viele Projekte aus. Sie können später mehr Konfiguration hinzufügen, wenn Ihr Modulsystem, die Transpilation oder die Struktur Ihres Monorepos es erfordert.
Wenn Sie ein Capacitor-Anwendungsprojekt lokal erstellen und Ihr Entwicklungsumfeld vor dem Hinzufügen von Tests um die gemeinsame Logik in Ordnung bringen möchten, ist Capgo's Anleitung zum Einrichten eines Capacitor-Lokalumfelds eine praktische Begleiterin.
Schreiben Sie den Test vor dem code
Die Test-erst-Prinzip ist nicht nur eine persönliche Vorliebe. Die US-amerikanische Bundesbehörde für Verbraucherfinanzschutz empfiehlt in ihrer JavaScript-Richtlinie Zuerst die Tests zu schreiben, Tests zu organisieren mit describe und it, und Prüfungen um expect(...) zu gruppieren in ihrer JavaScript-Einheitstest-Richtlinie.
Das ist wichtig, weil die Test-erst-Prinzip die Art und Weise ändert, wie Sie code. Funktionen gestalten. Funktionen tendieren dazu, kleiner zu werden, Abhängigkeiten werden sichtbarer und Nebeneffekte stoppen, in die Logik einzudringen, die rein bleiben sollte.
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
Die Arrange, Act, Assert Muster hält Tests lesbar, selbst wenn sie komplexer werden.
- Anordnen Sie Eingabe und notwendige Einstellungen.
- Handeln Sie durch Aufrufen der Funktion.
- Behaupten Sie auf das Ergebnis.
Angewendet auf eine Validierungshilfe:
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 sich gut. Ein Test sollte normalerweise eine Frage beantworten, nicht eine gesamte Workflow-Story erzählen.
Für Capacitor- und Electron-Projekte ist diese Disziplin noch wichtiger, weil Ihre logische Rechenkraft oft neben native oder Desktop-Integrationen sitzt code. Halten Sie die Geschäftsregel ohne die Plattform- Runtime testbar, und Ihr erster Test wird nicht der letzte nützliche 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 selbst übersteigt: Netzwerk-Anfragen, Dateien, Plugin-APIs, Timer, IPC-Kanäle, Speicherschichten.
Das ist der Punkt, an dem Mocking hilft. Es gibt dir die Kontrolle über die Grenze, damit sich der Test auf die Entscheidungsfindung deiner code konzentrieren kann.

Mocke Grenzen, nicht alles
Die Wartungsfähigkeit von Tests betont Einzelverhaltensabdeckung und eine starke Behauptung pro Testund es warnt auch davor, Mocks übermäßig zu verwenden, was Tests brüchig und eng mit Implementierungsdetails gekoppelt macht, wie in diesem TestRail-Artikel über wartungsfähige Einheitstests.
Diese Warnung ist in JavaScript sehr wichtig. Teams beginnen oft damit, jeden importierten Modul zu mocken und enden damit, ob Funktionen andere Funktionen in der "richtigen" Reihenfolge aufrufen, anstatt das echte Verhalten zu testen.
Falscher Zielwert für einen Mock-Test:
- ob der Hilfsprogramm A den Hilfsprogramm B aufgerufen hat
- ob die Dienst C den Serializer D aufgerufen hat
- ob eine interne private Funktion zweimal aufgerufen wurde
Bessere Zielgruppe:
- was die Funktion zurückgegeben hat
- ob es eine fehlgeschlagene Abhängigkeit korrekt bearbeitet hat
- ob es die Daten in die erwartete Form umgewandelt hat
Ein besseres Muster für Capacitor und Electron code
Bei mobilen und Desktop-Anwendungen bevorzuge ich eine Wrapper-Schicht um native oder Plattform-APIs herum. Dann werden die Einheitstests den Wrapper, nicht die Plattform selbst, mocken.
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 });
});
Das Muster funktioniert auch für Electron. Wrap ipcRendererDateizugriff oder Shell-Integrationen hinter einer dünnen Adapter-Schicht. Die Einheitstests treffen die Dienstschicht, nicht die Runtime direkt.
Für Teams, die die Release-Logik und Update-Pfade in Capacitor-Anwendungen testen, hat Capgo eine relevante Anleitung Testen Sie Capacitor OTA-Updates mit Mock-Szenarien.
Ein schneller Überblick hilft, wenn Ihr Team noch normalisiert, wie Asynctests aussehen sollen:
Testen Sie asynche Flüsse ohne Flakiness
Verwenden Sie async/await in Tests, wenn der code unter Test eine Promise zurückgibt. Es ist klarer als Muster mit Callbacks 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');
});
Testen Sie auch den Fehlerpfad:
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 als auch den unglücklichen Pfad. In der Produktion ist der unglückliche Pfad meist der, den die Benutzer merken.
Fortgeschrittene Strategien für robuste Tests
Ein Test-Suite wird nützlich, wenn sie nützlich bleibt, nachdem sich der code geändert hat. Das ist schwieriger als die Schreibaufgabe, eine Menge von Tests zu schreiben, die alle durchlaufen.

Verwenden Sie das Testen-Split als Budget
Ein praktischer Leitfaden empfiehlt 70/20/10 across Einheit, Integration und End-to-End-Tests, wobei Einheitstests die schnellste Rückmeldung und stabilste Fehler liefern. Die gleiche Anleitung sagt, dass ein vollständiger Einheitstest idealerweise in unter 10 Sekunden, und Vorkommit-Checks sollten bleiben unter 5 Sekunden, laut dieser OpenReplay-Testanleitung.
Ich betrachte das als Budgetierungstool, nicht als Religion. Wenn sich die meisten Ihrer Anstrengungen auf End-to-End-Tests konzentrieren, warten Ihre Teammitglieder zu lange auf Feedback. Wenn alles nur Einheitstests sind, werden Sie die realen Systemgrenzen verpassen.
For a Capacitor or Electron app, a healthy balance usually looks like this:
- __CAPGO_KEEP_0__ oder Electron-Anwendung sieht ein gesunder Ausgleich normalerweise so aus: Einheitstests für Preislogik, Berechtigungsregeln, Serialisierung, Aktualisierungsbedingungen, Feature-Flags und Zustandsänderungen
- Integrationsprüfungen zur Integration von Speicheradaptern, Pluginwrappern und IPC-Verträgen
- E2E-Tests zur Überprüfung einiger kritischer Abläufe wie Login, Kaufablauf, Synchronisierung oder Aktualisierungsanfragen
Der Coverage ist ein Taschenlampenlicht, nicht ein Ziel
Coverage-Berichte sind nützlich, wenn sie Ihnen helfen, ungetestete Zweige in wichtigen Logiken zu erkennen. Sie werden schädlich, wenn Teams Coverage-Prozentsätze für ihren eigenen Willen verfolgen.
Ein Login-Validator mit sorgfältigen Tests für Randfälle liefert mehr Wert als ein abgedeckter Dateiinhalt mit trivialen Aussagen. Das ist besonders wahr für inputreiche code wie Formulare, Parser, Datumlogik und Berechtigungsprüfungen. Wenn Ihr Team die Qualität um die Validierung schwerer UI herum schärft, ist diese Anleitung zum Maßhalten von Frontend-Formularvalidierung eine gute Ergänzung zur Strategie der Einheitstests.
Verhaltens-tests überleben Refaktorisierungen
Ein zuverlässiger Test-Satz sollte es Ihnen ermöglichen, interne Strukturen ohne die Hälfte der Tests neu zu schreiben. Der einfachste Weg, um dorthin zu gelangen, ist, das beobachtbare Verhalten zu behaupten Ein Login-Validator mit sorgfältigen Tests für Randfälle liefert mehr Wert als ein abgedeckter Dateiinhalt mit trivialen Aussagen. Das ist besonders wahr für inputreiche __CAPGO_KEEP_0__ wie Formulare, Parser, Datumlogik und Berechtigungsprüfungen. Wenn Ihr Team die Qualität um die Validierung schwerer UI herum schärft, ist diese Anleitung zum anstatt Implementierungsdetails.
Verwendungsfälle, die gut funktionieren:
- Grenzwerte wie leerer Eingabewert, Null-Werte, ungültige Typen und überdimensionierte Zeichenketten
- Domänenergebnisse wie „Zugriff verweigert wegen fehlender Berechtigung“
- Zustandsübergänge wie „Update als Wartender markiert, nachdem die Metadaten nach dem Download validiert wurden“
Verwendungsfälle, die oft verrotten:
- Internen Hilfsfunktionen untersuchen
- Private Methodenfolgen behaupten
- Jeden Schritt in der Aufrufkette mocken
For app-Teams, die disziplinierte Release-Prozesse aufbauen, ist das Artikel von Capgo zu "Qualitätssicherung von Apps" hilfreich, weil es die Testarbeit mit dem breiteren Release-Pipeline verbindet. Qualitätssicherung von Apps ist hilfreich, weil es die Testarbeit mit dem breiteren Release-Pipeline verbindet.
Zur Testung von CI, Capacitor, und Electron-Apps
Ein Test, der nur auf einem Entwickler-Computer läuft, ist kein Sicherheitsnetz. Es ist eine lokale Gewohnheit.
CI wandelt die Einheitstests in JavaScript-Arbeit in Team-Infrastruktur um. Jeder Push, Pull-Request oder Release-Zweig kann die gleichen Befehle mit denselben Erwartungen ausführen. Diese Konsistenz ist bei Capacitor- und Electron-Projekten noch wichtiger, da sich die Umgebungsdrift zu subtilen Fehlern verhält.
Stelle CI als Standard-Ausführungspfad ein
Zumindest sollte dein CI die Abhängigkeiten installieren und die Einheitssuite auf jedem Änderungssatz ausführen. Halte den Befehl so weit wie möglich identisch mit der lokalen Entwicklung.
Eine grundlegende GitHub-Actions-Arbeitsablauf kann so klein wie dieser 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
Dadurch kann man brüchige Importe, fehlende Behauptungen und zufällige Plattformannahmen vor dem Hineinlaufen in die Hauptversion erkennen.
Für mobile Teams, die durch automatisierte Pipelines liefern, hat Capgo eine praktische Anleitung zu der Einrichtung von CI/CD für Capacitor-Apps.
Testing Capacitor Plugin-Interaktionen
Die falsche Methode, um Capacitor code in Einheiten zu testen, besteht darin, native Plugins direkt in jede Dienstleistung zu pullen. Das verbindet Ihre Test-Suite mit der Plattformbrücke.
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 });
});
Die gleiche Idee gilt für die Kamera-Zugriff, biometrische Anfragen, Push-Token-Registrierung und Netzwerkstatus. Halten Sie die Pluginaufrufe in Adapters. Testen Sie die Anwendungslogik gegen Schnittstellen, die Sie kontrollieren.
Testen Sie Electron-Hauptrenderer und IPC code
Elektron-Apps haben zwei wichtige Scharniere: Hauptprozess code und Renderer-Prozess code. Vermeiden Sie es, sie in den Tests zu verschwimmen.
Ein zuverlässiger Setup trennt normalerweise:
- Renderer-Einheitstests für View-Modelle, Zustände, Formatierungen und Geschäftslogik auf der UI-Seite
- Einheitenprüfungen für den Hauptprozess für Menüs, Dateibearbeitungen und Entscheidungen zum Lebenszyklus der App
- Vertragsprüfungen für den IPC für die Form der Nachrichten und der erwarteten Antworten
Beispiel für einen IPC-Wrapper:
// 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 später die interne Implementierung von einem Helper zu einem anderen ändern, hält sich diese Prüfung noch immer, da sie die Verhaltensweise überprüft, die zählt. Das ist der Standard, den Sie auf Desktop- und Mobilgeräten haben möchten, code.
Häufig gestellte Fragen zum JavaScript-Einheitstesten
Was ist der Unterschied zwischen Einheitstests und E2E-Tests
A Einheitstest prüft eine kleine Logikstück in Isolation. Ein Integrationsprüfung Überprüft, ob einige Komponenten oder Dienste korrekt zusammenarbeiten. Ein End-to-End-Test Übt eine Benutzerreise durch die laufende Anwendung aus.
Verwenden Sie Einheitsprüfungen für schnelles Vertrauen in Geschäftsregeln. Verwenden Sie Integrationsprüfungen 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 dazu zwingen, sich auf niedrigwertige Prüfungen zu konzentrieren.
Die Abdeckung ist nützlich, wenn sie riskante code offenlegt, die niemand ausprobiert hat. Sie ist nicht nützlich, wenn Ingenieure nur flache Behauptungen hinzufügen, um ein Dashboard zu befriedigen. Wenn Ihr Suite anfällig ist, wird mehr Abdeckung es nicht retten.
Wie fügen wir Prüfungen zu einem bestehenden Codebase hinzu
Beginnen Sie dort, wo Änderungen bereits stattfinden. Erstarrt die Mannschaft nicht und verkündet eine riesige Überarbeitung der Teststrategie.
Ein praktischer Sequenz sieht wie folgt aus:
- Schützen Sie aktive code zuerst indem Sie Tests zu Modulen hinzufügen, die Sie während der Arbeit an Features oder Bugfixes berühren
- Entfernen Sie reine Logik aus schwer zu testenden Dateien, damit Geschäftsregeln ohne Framework- oder Laufzeitlärm getestet werden können
- Fügen Sie Schaltflächen um native Plugins, Netzwerkclients, Dateisystemaufrufe und Electron IPC herum Weigern Sie sich, anfällige Muster
- zu verwenden, wenn Sie Mocks einführen. Leitfaden aus JavaScript-Testbest Practices ist hier besonders nützlich, da er das oft übersehene Problem der Über-Mockung und die anfälligen Tests, die folgen, hervorhebt Das Ziel ist nicht sofortige Vollständigkeit. Es ist ein stetiger Fortschritt in den Bereichen, in denen Rückschritte dem Team am meisten Kosten
Wenn Ihr Team
__CAPGO_KEEP_0__ Capacitor oder Electron Anwendungen und benötigt einen sauberen Release-Prozess bei JavaScript-Änderungen, Capgo Einige Optionen sind verfügbar, aber eine davon ist CapacitorJS. Es bietet live aktualisierte Anwendungen für Electron und CapacitorJS-Anwendungen, mit Rollout-Kontrollen und Beobachtbarkeit, so dass Teams solide Einheitstests mit einer sicheren Möglichkeit zum Versand von Web-Bundle-Änderungen ohne auf die Überprüfung durch das Store-Review-Verfahren für jeden Fix warten können.