_
_
SuperTest Cheatsheet¶
• Installation
| Platform | Command |
|---|---|
| npm (All Platforms) | INLINE_CODE_20 |
| Yarn (All Platforms) | INLINE_CODE_21 |
| With Jest | INLINE_CODE_22 |
| With Mocha | INLINE_CODE_23 |
| With TypeScript | INLINE_CODE_24 |
| Specific Version | INLINE_CODE_25 |
| _ | |
| Standard HTTP Methoden |
| Command | Description |
|---|---|
| INLINE_CODE_26 | Send GET request to endpoint |
| INLINE_CODE_27 | Send POST request to endpoint |
| INLINE_CODE_28 | Send PUT request to update resource |
| INLINE_CODE_29 | Send PATCH request for partial update |
| INLINE_CODE_30 | Send DELETE request to remove resource |
| INLINE_CODE_31 | Send HEAD request (headers only) |
| INLINE_CODE_32 | Send OPTIONS request for CORS preflight |
| INLINE_CODE_33 | Send JSON data in request body |
| INLINE_CODE_34 | Add query parameters to URL |
| INLINE_CODE_35 | Set request header |
| INLINE_CODE_36 | Assert HTTP status code |
| INLINE_CODE_37 | Assert response header value |
| INLINE_CODE_38 | Execute request with callback |
| INLINE_CODE_39 | Execute request with Promise/async-await |
| _ | |
| Beschwörungen und Erwartungen |
| Command | Description |
|---|---|
| INLINE_CODE_40 | Expect exact status code |
| INLINE_CODE_41 | Expect status and exact body match |
| INLINE_CODE_42 | Expect exact header value |
| INLINE_CODE_43 | Expect header matching regex |
| INLINE_CODE_44 | Custom assertion function |
| INLINE_CODE_45 | Expect status and body matching regex |
| INLINE_CODE_46 | Expect redirect location header |
| INLINE_CODE_47 | Expect exact JSON body match |
Konfiguration anfordern
| Command | Description |
|---|---|
| INLINE_CODE_48 | Set single request header |
| INLINE_CODE_49 | Set multiple headers |
| INLINE_CODE_50 | Set HTTP Basic Authentication |
| INLINE_CODE_51 | Add form field (multipart) |
| INLINE_CODE_52 | Attach file for upload |
| INLINE_CODE_53 | Attach file from buffer |
| INLINE_CODE_54 | Set request timeout in milliseconds |
| INLINE_CODE_55 | Follow up to 5 redirects |
| INLINE_CODE_56 | Set Content-Type header |
| INLINE_CODE_57 | Set Accept header |
| INLINE_CODE_58 | Send raw string body |
| INLINE_CODE_59 | Send binary data |
| _ | |
| / Fortgeschrittene Nutzung |
| Command | Description |
|---|---|
| INLINE_CODE_60 | Create agent for persistent cookies |
| INLINE_CODE_61 | Use agent for authenticated requests |
| INLINE_CODE_62 | Test external API endpoints |
| INLINE_CODE_63 | Custom response parser |
| INLINE_CODE_64 | Buffer response body |
| INLINE_CODE_65 | Set expected response type |
| INLINE_CODE_66 | Retry failed requests 3 times |
| INLINE_CODE_67 | Set custom CA certificate |
| INLINE_CODE_68 | Set client certificate |
| INLINE_CODE_69 | Set client private key |
| INLINE_CODE_70 | Set PFX/PKCS12 certificate |
| INLINE_CODE_71 | Disable TLS certificate validation |
Testen von Mustern
| Pattern | Description |
|---|---|
| INLINE_CODE_72 | Store response for multiple assertions |
| INLINE_CODE_73 | Assert on response body with test framework |
| INLINE_CODE_74 | Assert on response headers |
| INLINE_CODE_75 | Alternative status assertion |
| INLINE_CODE_76 | Parallel request testing |
| INLINE_CODE_77 | Sequential test requests |
| _ | |
| Konfiguration |
Basic Test Setup¶
// test/setup.js
const request = require('supertest');
const app = require('../app');
module.exports = { request, app };
Jest Konfiguration¶
// jest.config.js
module.exports = {
testEnvironment: 'node',
testMatch: ['**/__tests__/**/*.test.js'],
collectCoverageFrom: ['src/**/*.js'],
coveragePathIgnorePatterns: ['/node_modules/']
};
Mocha Konfiguration¶
Paket.json Scripts¶
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:api": "jest --testPathPattern=api"
}
}
Umgebungsvariablen¶
// config/test.js
module.exports = {
port: process.env.TEST_PORT || 3001,
database: process.env.TEST_DB || 'test_db',
apiTimeout: process.env.API_TIMEOUT || 5000
};
Häufige Anwendungsfälle
Use Case 1: Testen von REST API CRUD Operationen¶
const request = require('supertest');
const app = require('../app');
describe('User API', () => {
let userId;
// Create
test('POST /api/users - create user', async () => {
const res = await request(app)
.post('/api/users')
.send({ name: 'John Doe', email: 'john@example.com' })
.expect(201)
.expect('Content-Type', /json/);
userId = res.body.id;
expect(res.body.name).toBe('John Doe');
});
// Read
test('GET /api/users/:id - get user', async () => {
await request(app)
.get(`/api/users/${userId}`)
.expect(200)
.expect((res) => {
expect(res.body.name).toBe('John Doe');
});
});
// Update
test('PUT /api/users/:id - update user', async () => {
await request(app)
.put(`/api/users/${userId}`)
.send({ name: 'Jane Doe' })
.expect(200);
});
// Delete
test('DELETE /api/users/:id - delete user', async () => {
await request(app)
.delete(`/api/users/${userId}`)
.expect(204);
});
});
Use Case 2: Testing Authentication Flow¶
const request = require('supertest');
const app = require('../app');
describe('Authentication', () => {
let authToken;
test('POST /auth/register - register new user', async () => {
await request(app)
.post('/auth/register')
.send({
email: 'test@example.com',
password: 'SecurePass123!',
name: 'Test User'
})
.expect(201);
});
test('POST /auth/login - login user', async () => {
const res = await request(app)
.post('/auth/login')
.send({
email: 'test@example.com',
password: 'SecurePass123!'
})
.expect(200)
.expect('Content-Type', /json/);
authToken = res.body.token;
expect(authToken).toBeDefined();
});
test('GET /api/profile - access protected route', async () => {
await request(app)
.get('/api/profile')
.set('Authorization', `Bearer ${authToken}`)
.expect(200)
.expect((res) => {
expect(res.body.email).toBe('test@example.com');
});
});
test('GET /api/profile - reject without token', async () => {
await request(app)
.get('/api/profile')
.expect(401);
});
});
Use Case 3: Dateiaufladung testen¶
const request = require('supertest');
const app = require('../app');
const path = require('path');
describe('File Upload', () => {
test('POST /api/upload - upload single file', async () => {
const filePath = path.join(__dirname, 'fixtures', 'test.pdf');
const res = await request(app)
.post('/api/upload')
.attach('document', filePath)
.field('title', 'Test Document')
.field('description', 'A test file upload')
.expect(200)
.expect('Content-Type', /json/);
expect(res.body.filename).toMatch(/\.pdf$/);
expect(res.body.size).toBeGreaterThan(0);
});
test('POST /api/upload - upload multiple files', async () => {
await request(app)
.post('/api/upload/multiple')
.attach('files', 'test/fixtures/file1.pdf')
.attach('files', 'test/fixtures/file2.pdf')
.expect(200)
.expect((res) => {
expect(res.body.files).toHaveLength(2);
});
});
});
Use Case 4: Prüfung mit dauerhaften Sitzungen¶
const request = require('supertest');
const app = require('../app');
describe('Session Management', () => {
const agent = request.agent(app);
test('Login and maintain session', async () => {
// Login
await agent
.post('/auth/login')
.send({ username: 'user', password: 'pass' })
.expect(200);
// Session persists - can access protected route
await agent
.get('/api/dashboard')
.expect(200);
// Session still valid for subsequent requests
await agent
.get('/api/profile')
.expect(200);
// Logout
await agent
.post('/auth/logout')
.expect(200);
// Session expired - access denied
await agent
.get('/api/dashboard')
.expect(401);
});
});
Use Case 5: Testfehlerbehandlung¶
const request = require('supertest');
const app = require('../app');
describe('Error Handling', () => {
test('404 - Resource not found', async () => {
await request(app)
.get('/api/users/99999')
.expect(404)
.expect((res) => {
expect(res.body.error).toBe('User not found');
expect(res.body.code).toBe('USER_NOT_FOUND');
});
});
test('400 - Validation error', async () => {
await request(app)
.post('/api/users')
.send({ name: '' }) // Invalid data
.expect(400)
.expect((res) => {
expect(res.body.errors).toBeDefined();
expect(res.body.errors.name).toContain('required');
});
});
test('429 - Rate limit exceeded', async () => {
// Make multiple requests to trigger rate limit
const requests = Array(101).fill().map(() =>
request(app).get('/api/users')
);
const responses = await Promise.all(requests);
const rateLimited = responses.find(r => r.status === 429);
expect(rateLimited).toBeDefined();
expect(rateLimited.body.error).toMatch(/rate limit/i);
});
test('500 - Internal server error', async () => {
await request(app)
.get('/api/trigger-error')
.expect(500)
.expect((res) => {
expect(res.body.error).toBe('Internal server error');
});
});
});
oder Best Practices
-
** Verwenden Sie async/await syntax**: Reiniger und lesbarer als Callbacks. Modern JavaScript unterstützt dieses Muster native.
javascript const res = await request(app).get('/api/users').expect(200);_ -
**Installieren als dev Abhängigkeit*: SuperTest ist ein Test-Tool und sollte nur in
devDependenciessein, nicht Produktionsabhängigkeiten.bash npm install supertest --save-dev_ -
** Starten Sie den Server nicht manuell*: SuperTest behandelt die Serverbindung automatisch. Passen Sie die Express-App direkt ohne Anruf
app.listen(). ```javascript // Good: Export app without listening module.exports = app;
// Bad: Don't do this in test files app.listen(3000); ```_
-
**Beantragung.agent() für Sitzungstests*: Wenn Sie authentische Routen oder Cookie-basierte Sitzungen testen, erstellen Sie einen Agenten, um Cookies auf Anfrage zu bestehen.
javascript const agent = request.agent(app); await agent.post('/login').send(credentials); await agent.get('/protected'); // Cookies persist_ -
** Erwartungen für sauberere Tests*: Mehrere
.expect()Anrufe können in einem einzigen Test für umfassende Behauptungen gekettet werden.javascript await request(app) .get('/api/users') .expect(200) .expect('Content-Type', /json/) .expect((res) => expect(res.body).toHaveLength(10));_ -
**Store Antworten für komplexe Behauptungen*: Erfassen Sie das Antwortobjekt, wenn Sie mehrere Behauptungen auf verschiedenen Teilen durchführen müssen.
javascript const res = await request(app).get('/api/users').expect(200); expect(res.body).toHaveLength(5); expect(res.headers['x-total-count']).toBe('100');_ -
** Testen Sie beide Erfolgs- und Ausfallfälle*: Testen Sie immer Fehlerszenarien, Validierungsfehler und Randfälle entlang glücklicher Pfade.
javascript test('returns 404 for non-existent user', async () => { await request(app).get('/api/users/99999').expect(404); });_ -
**Benutze beschreibende Testnamen*: Testbeschreibungen schreiben, die deutlich erklären, welches Verhalten überprüft wird.
javascript test('POST /api/users returns 400 when email is missing', async () => { // Test implementation });_ -
** Prüfdaten nach oben*: Verwenden Sie
beforeEachafterEach, um den Datenbankzustand zurückzusetzen und die Testisolation zu gewährleisten.javascript afterEach(async () => { await User.deleteMany({}); }); -
**Stimmen einstellen*: Für langsame Endpunkte oder externe API-Anrufe konfigurieren Sie Timeout-Werte, um Fehlausfälle zu verhindern.
javascript await request(app).get('/api/slow').timeout(10000).expect(200);_
Fehlerbehebung
| Issue | Solution |
|---|---|
| INLINE_CODE_83 | Don't call INLINE_CODE_84 in your app file when testing. Export the app without starting the server, or use different ports for testing. |
| Tests hang and never complete | Ensure database connections are closed after tests. Use INLINE_CODE_85 to close connections: INLINE_CODE_86 |
| INLINE_CODE_87 | Missing INLINE_CODE_88 keyword or INLINE_CODE_89 callback. Always use INLINE_CODE_90 with async/await or provide INLINE_CODE_91 callback. |
| Headers already sent error | You're sending multiple responses in your route handler. Ensure only one INLINE_CODE_92, INLINE_CODE_93, or similar call per request. |
| Timeout errors on slow endpoints | Increase timeout with INLINE_CODE_94 or adjust global timeout in test framework config: INLINE_CODE_95 |
| Authentication tests fail randomly | Use INLINE_CODE_96 to persist cookies/sessions across requests instead of separate INLINE_CODE_97 calls. |
| File upload tests fail | Verify file path is correct using INLINE_CODE_98. Ensure multipart middleware is configured in app. |
| CORS errors in tests | CORS is typically a browser concern. SuperTest bypasses CORS. If testing CORS headers, use INLINE_CODE_99 request with Origin header. |
| SSL/TLS certificate errors | Use INLINE_CODE_100 for testing environments or provide valid certificates with INLINE_CODE_101, INLINE_CODE_102, INLINE_CODE_103 methods. |
| Response body is empty Buffer | Response might be binary. Use INLINE_CODE_104 or check Content-Type. For JSON, ensure server sends correct Content-Type header. |
| Tests pass individually but fail together | Tests aren't isolated. Clear database/state between tests using INLINE_CODE_105/INLINE_CODE_106 hooks. Check for shared mutable state. |
| Kann externe APIs nicht testen | SuperTest funktioniert mit externen URLs: __INLINE_CODE_107_. Stellen Sie sicher, dass Netzwerkzugriff und API-Verfügbarkeit. |