Unit-Tests für NodeJS mit Mocha und Chai
Oct 26, 2024 am 06:58 AM
Unit-Tests sind wichtig, da sie kleine Teile des Codes überprüfen, um sicherzustellen, dass sie richtig funktionieren, und Fehler frühzeitig finden. Es ist wichtig, diese Tests durchzuführen, bevor eine App veröffentlicht wird. In diesem Leitfaden werden Unit-Tests mit Mocha und Chai behandelt.
Warum Mokka und Chai?
Mocha ist ein funktionsreiches JavaScript-Testframework, das auf Node.js läuft und asynchrone Tests einfach und angenehm macht. Es bietet Funktionen, die in einer bestimmten Reihenfolge ausgeführt werden, Testergebnisse sammeln und genaue Berichte liefern.
Chai ist eine BDD/TDD-Assertionsbibliothek, die mit jedem JavaScript-Test-Framework verwendet werden kann. Es bietet mehrere Schnittstellen, sodass Entwickler den Behauptungsstil wählen können, den sie am bequemsten finden.
Vorteile der Verwendung von Mokka und Chai
Lesbare und aussagekräftige Aussagen
Chai bietet verschiedene Assertionsstile und Syntaxoptionen, die gut mit Mocha funktionieren, sodass Sie den Stil auswählen können, der Ihren Anforderungen an Klarheit und Lesbarkeit entspricht.Unterstützung für asynchrone Tests
Mocha handhabt asynchrone Tests problemlos, sodass Sie asynchronen Code in Node.js-Anwendungen testen können, ohne dass zusätzliche Bibliotheken oder komplexe Setups erforderlich sind.
Einrichten der Testumgebung
Abhängigkeiten installieren
Zuerst richten wir ein neues Node.js-Projekt ein und installieren die notwendigen Abhängigkeiten:
1 2 3 4 5 6 7 8 9 |
|
Richten Sie Testskripte ein
Fügen Sie die folgenden Skripte zu Ihrem package.json hinzu:
1 2 3 4 5 6 |
|
Projektübersicht
Bevor wir uns mit dem Testen befassen, wollen wir uns mit der Anwendung befassen, die wir testen werden. Wir erstellen eine einfache, aber sichere Authentifizierungs-API mit den folgenden Funktionen.
Anwendungsstruktur
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
API-Endpunkte
- Authentifizierungsendpunkte:
1 2 3 4 5 6 7 8 9 |
|
- Benutzerendpunkte:
1 2 3 4 5 6 7 8 9 10 |
|
Umgebungseinrichtung zum Testen
Erstellen Sie eine .env.test-Datei für die testspezifische Konfiguration:
1 2 3 |
|
Teststruktur verstehen
Lassen Sie uns unsere erste Testdatei test/auth.test.js erstellen
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Testen Sie Lifecycle-Hooks
Mocha bietet mehrere Hooks für den Testaufbau und die Bereinigung:
before(): Wird einmal vor allen Tests ausgeführt
after(): Wird nach allen Tests einmal ausgeführt
beforeEach(): Wird vor jedem Test ausgeführt
afterEach(): Wird nach jedem Test ausgeführt
Mochas write()- und it()-Blöcke
Tests werden mithilfe von beschreiben()-Blöcken zum Gruppieren verwandter Tests und it()-Blöcken für einzelne Testfälle organisiert:
1 2 3 4 5 6 7 8 9 |
|
Schreiben unserer ersten Testsuite
Testen der Registrierung und Anmeldung
1 2 3 4 5 6 |
|
Authentifizierung testen
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Datenbanktests
Testdatenbank einrichten
1 2 3 4 5 6 7 8 9 |
|
Testen von CRUD-Operationen
1 2 3 4 5 6 7 8 9 10 |
|
Best Practices
Behalten Sie Test Atomic bei
Jeder Test sollte für sich allein stehen und nicht von anderen Tests abhängig sein
Tests sollten in beliebiger Reihenfolge ausgeführt werden können
-
Verwenden Sie die Hooks „before“, „after“, „beforeEach“ und „afterEach“ für die ordnungsgemäße Einrichtung und Bereinigung
1
2
3
PORT=3001
MONGODB_URI=mongodb:
//localhost:27017/auth-api-test
JWT_SECRET=your-test-secret-key
Nach dem Login kopierenNach dem Login kopierenFolgen Sie dem AAA-Muster
- Anordnen: Testdaten und -bedingungen einrichten
- Aktion: Den zu testenden Code ausführen
- Bestätigen: Überprüfen Sie die Ergebnisse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const
chai =
require
(
'chai'
);
const
chaiHttp =
require
(
'chai-http'
);
const
app =
require
(
'../src/app'
);
const
User =
require
(
'../src/models/user.model'
);
chai.
use
(chaiHttp);
const
expect = chai.expect;
describe(
'Auth API Tests'
, () => {
// Runs before all tests
before(async () => {
await User.deleteMany({});
});
// Runs after each test
afterEach(async () => {
await User.deleteMany({});
});
// Test suites will go here
});
Nach dem Login kopierenNach dem Login kopierenTesten Sie Edge-Fälle
Testen Sie Randbedingungen, Fehlerszenarien, ungültige Eingaben und leere oder Nullwerte.
1
2
3
4
5
6
7
8
9
10
11
describe(
'Auth API Tests'
, () => {
describe(
'POST /api/auth/register'
, () => {
it(
'should register a new user successfully'
, async () => {
// Test implementation
});
it(
'should return error when email already exists'
, async () => {
// Test implementation
});
});
});
Nach dem Login kopierenVerwenden Sie beschreibende Testnamen
Testnamen sollten das getestete Szenario klar beschreiben, einer konsistenten Namenskonvention folgen und das erwartete Verhalten enthalten.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
describe(
'POST /api/auth/register'
, () => {
it(
'should register a new user successfully'
, async () => {
const
res = await chai
.request(app)
.post(
'/api/auth/register'
)
.send({
email:
'test@example.com'
,
password:
'Password123!'
,
name:
'Test User'
});
expect(res).to.have.status(201);
expect(res.body).to.have.property(
'token'
);
expect(res.body).to.have.property(
'user'
);
expect(res.body.user).to.have.property(
'email'
,
'test@example.com'
);
});
it(
'should return 400 when email already exists'
, async () => {
// First create a user
await chai
.request(app)
.post(
'/api/auth/register'
)
.send({
email:
'test@example.com'
,
password:
'Password123!'
,
name:
'Test User'
});
// Try to create another user with same email
const
res = await chai
.request(app)
.post(
'/api/auth/register'
)
.send({
email:
'test@example.com'
,
password:
'Password123!'
,
name:
'Test User 2'
});
expect(res).to.have.status(400);
expect(res.body).to.have.property(
'error'
);
});
});
Nach dem Login kopierenScheinen Sie externe Abhängigkeiten
- Verwenden Sie Stubs und Mocks für externe Dienste
- Isolieren Sie den zu testenden Code
- Kontrolltestumgebung
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
describe(
'Protected Routes'
, () => {
let token;
let userId;
beforeEach(async () => {
// Create a test user and get token
const
res = await chai
.request(app)
.post(
'/api/auth/register'
)
.send({
email:
'test@example.com'
,
password:
'Password123!'
,
name:
'Test User'
});
token = res.body.token;
userId = res.body.user._id;
});
it(
'should get user profile with valid token'
, async () => {
const
res = await chai
.request(app)
.get(
'/api/users/profile'
)
.set(
'Authorization'
, `Bearer ${token}`);
expect(res).to.have.status(200);
expect(res.body).to.have.property(
'email'
,
'test@example.com'
);
});
it(
'should return 401 with invalid token'
, async () => {
const
res = await chai
.request(app)
.get(
'/api/users/profile'
)
.set(
'Authorization'
,
'Bearer invalid-token'
);
expect(res).to.have.status(401);
});
});
Nach dem Login kopierenGehen Sie mit Versprechen richtig um
- Zusagen immer zurückgeben oder async/await verwenden
- Verwenden Sie die richtige Fehlerbehandlung
- Testen Sie sowohl Erfolgs- als auch Misserfolgsfälle
1
2
3
4
5
6
7
8
9
10
const
mongoose =
require
(
'mongoose'
);
before(async () => {
await mongoose.connect(process.env.MONGODB_URI_TEST);
});
after(async () => {
await mongoose.connection.dropDatabase();
await mongoose.connection.close();
});
Nach dem Login kopierenLegen Sie geeignete Zeitüberschreitungen fest
- Legen Sie realistische Zeitüberschreitungen für asynchrone Vorgänge fest
- Globale Timeouts in der Mocha-Konfiguration konfigurieren
- Überschreiben Sie bei Bedarf Zeitüberschreitungen für bestimmte Tests
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
describe(
'User CRUD Operations'
, () => {
it(
'should update user profile'
, async () => {
const
res = await chai
.request(app)
.put(`/api/users/${userId}`)
.set(
'Authorization'
, `Bearer ${token}`)
.send({
name:
'Updated Name'
});
expect(res).to.have.status(200);
expect(res.body).to.have.property(
'name'
,
'Updated Name'
);
});
it(
'should delete user account'
, async () => {
const
res = await chai
.request(app)
.
delete
(`/api/users/${userId}`)
.set(
'Authorization'
, `Bearer ${token}`);
expect(res).to.have.status(200);
// Verify user is deleted
const
user = await User.findById(userId);
expect(user).to.be.null;
});
});
Nach dem Login kopieren
Wir stellen vor: Keploy Unit Test Generator
Das Schreiben manueller Testfälle für Mokka mit Chai ist zwar effektiv, birgt jedoch oft mehrere Herausforderungen:
Zeitaufwändig: Die manuelle Erstellung detaillierter Testsuiten kann viel Zeit in Anspruch nehmen, insbesondere bei großen Codebasen.
Schwierig zu warten: Wenn sich Ihre Anwendung ändert, wird die Aktualisierung und Wartung manueller Tests komplexer und fehleranfälliger.
Inkonsistente Abdeckung: Entwickler konzentrieren sich möglicherweise auf die Hauptpfade, fehlende Randfälle oder Fehlerszenarien, die Fehler in der Produktion verursachen könnten.
Fähigkeitsabhängig: Die Qualität und Wirksamkeit manueller Tests hängen stark von den Testfähigkeiten des Entwicklers und seiner Vertrautheit mit der Codebasis ab.
Repetitiv und mühsam: Das Schreiben ähnlicher Teststrukturen für mehrere Komponenten oder Funktionen kann langweilig sein und möglicherweise zu weniger Liebe zum Detail führen.
Verzögertes Feedback: Die zum Schreiben manueller Tests benötigte Zeit kann die Entwicklung verlangsamen und wichtige Rückmeldungen zur Codequalität und -funktionalität verzögern.
Um diese Probleme anzugehen, hat Keploy ein ut-gen eingeführt, das KI nutzt, um den Testprozess zu automatisieren und zu verbessern. Dies ist die erste Implementierung des Meta LLM-Forschungspapiers, das Codesemantik versteht und aussagekräftige Unit-Tests erstellt.
Ziel ist es, die Unit-Test-Generierung (UTG) durch die schnelle Erstellung gründlicher Unit-Tests zu automatisieren. Dadurch wird der Bedarf an repetitiver manueller Arbeit reduziert, Randfälle verbessert, indem die Tests erweitert werden, um komplexere Szenarien abzudecken, die häufig manuell übersehen werden, und die Testabdeckung erhöht, um eine vollständige Abdeckung sicherzustellen, wenn die Codebasis wächst.
%[https://marketplace.visualstudio.com/items?itemName=Keploy.keployio]
Hauptfunktionen
Automatisierte Unit-Test-Generierung (UTG): Generieren Sie schnell umfassende Unit-Tests und reduzieren Sie redundanten manuellen Aufwand.
Randfälle verbessern: Erweitern und verbessern Sie den Testumfang, um komplexere Szenarien abzudecken, die häufig manuell übersehen werden.
Erhöhung der Testabdeckung: Mit zunehmender Codebasis wird es möglich, eine umfassende Abdeckung sicherzustellen.
Abschluss
Zusammenfassend lässt sich sagen, dass die Beherrschung des Node.js-Backend-Tests mit Mocha und Chai wichtig für Entwickler ist, die möchten, dass ihre Anwendungen zuverlässig und stark sind. Durch die Verwendung des Test-Frameworks von Mocha und der Clear-Assertion-Bibliothek von Chai können Entwickler detaillierte Testsuiten erstellen, die viele Teile ihres Codes abdecken, von einfachen Unit-Tests bis hin zu komplexen asynchronen Vorgängen. Das Befolgen von Best Practices wie die Fokussierung der Tests, die Verwendung klarer Namen und der korrekte Umgang mit Versprechen kann Ihren Testprozess erheblich verbessern. Durch den Einsatz dieser Tools und Techniken in Ihrem Entwicklungsworkflow können Sie Fehler frühzeitig finden, die Codequalität verbessern und sicherere und effizientere Anwendungen bereitstellen.
FAQs
Was ist der Unterschied zwischen Mokka und Chai und brauche ich beides?
Obwohl es sich bei beiden um Testwerkzeuge handelt, dienen sie unterschiedlichen Zwecken. Mocha ist ein Test-Framework, das die Struktur zum Organisieren und Ausführen von Tests bereitstellt (mithilfe der Blöcke „beschreiben()“ und „it()“). Chai ist eine Assertionsbibliothek, die Funktionen zum Überprüfen von Ergebnissen bereitstellt (wie „expect()“, „should“ und „assertion“). Während Sie Mokka ohne Chai verwenden können, erhalten Sie durch die gemeinsame Verwendung eine umfassendere und ausdrucksstärkere Testlösung.
Wie richte ich Testdaten zwischen Tests ein und bereinige sie?
Mocha bietet mehrere Lebenszyklus-Hooks für die Verwaltung von Testdaten:
before(): Vor allen Tests einmal ausführen
beforeEach(): Vor jedem Test ausführen
afterEach(): Nach jedem Test ausführen
after(): Nach allen Tests einmal ausführen
Beispiel:
1 2 3 4 5 6 7 8 9 |
|
Wie sollte ich meine Tests für eine bessere Organisation und Wartung strukturieren?
Gruppieren Sie verwandte Tests mithilfe von beschreiben()-Blöcken
Verwenden Sie beschreibende Testnamen, die das erwartete Verhalten klar zum Ausdruck bringen
Folgen Sie bei jedem Test dem AAA-Muster (Arrange-Act-Assert)
Tests atomar und unabhängig halten
Testdateien so organisieren, dass sie Ihre Quellcodestruktur widerspiegeln
Beispiel:
1 2 3 4 5 6 |
|
Was ist der Unterschied zwischen before, beforeEach, after und afterEach?
„before“ wird einmal vor allen Tests ausgeführt, „beforeEach“ wird vor jedem einzelnen Test ausgeführt, „afterEach“ wird nach jedem einzelnen Test ausgeführt und „after“ wird einmal ausgeführt, nachdem alle Tests abgeschlossen sind. Diese sind nützlich zum Einrichten und Bereinigen von Testdaten.
Wie teste ich asynchronen Code?
Sie können in Ihren Tests Async/Await- oder Return-Promises verwenden. Fügen Sie einfach „async“ vor Ihrer Testfunktion hinzu und verwenden Sie „await“, wenn Sie asynchrone Vorgänge aufrufen. Stellen Sie sicher, dass Sie für längere Vorgänge geeignete Zeitüberschreitungen festlegen.
Das obige ist der detaillierte Inhalt vonUnit-Tests für NodeJS mit Mocha und Chai. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heißer Artikel

Hot-Tools-Tags

Heißer Artikel

Heiße Artikel -Tags

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Ersetzen Sie Stringzeichen in JavaScript

Benutzerdefinierte Google -Search -API -Setup -Tutorial

8 atemberaubende JQuery -Seiten -Layout -Plugins

Erstellen Sie Ihre eigenen AJAX -Webanwendungen

10 JavaScript & JQuery MVC -Tutorials
