Playwright-Netzwerk-Interception und Mock
Dieses Kapitel stellt vor, wie man mit Playwright Netzwerkanfragen abfängt, ändert und mockt, wodurch unabhängige Tests ermöglicht werden, die nicht auf Backend-APIs angewiesen sind.
Was ist Netzwerk-Interception
Netzwerkinterzeption ermöglicht es dir, einzugreifen, wenn der Browser HTTP-Anfragen stellt.
Du kannstAnfragen blockieren, Antworten ändern und Mock-Daten zurückgeben, wodurch Tests unabhängig von externen APIs oder dem Netzwerkstatus werden.
page.route() Anfragen abfangen
page.route(url, handler)Wird verwendet, um alle Netzwerkanfragen abzufangen, die einem angegebenen URL-Muster entsprechen.
Grundlegende Interzeption
Beispiel
// Alle PNG- und JPEG-Bilder abfangen
await page.route('**/*.{png,jpg,jpeg}', route => route.abort());
// Zur Seite navigieren (Bilder werden nicht geladen)
await page.goto('https://www.example.com/');
// Die Seite lädt möglicherweise schneller, weil keine Bilder heruntergeladen werden
});
URL-AbgleichsmusterUnterstützt die folgenden Formate:
| Muster | Beispiel | Beschreibung |
|---|---|---|
| Vollständige URL | 'https://api.example.com/users' | Exakte Übereinstimmung |
| Glob-Platzhalter | '**/api/**' | **Entspricht jedem Pfad |
| Regulärer Ausdruck | /\/api\/v\d\/users/ | Flexibles Matching |
| Funktion | url => url.includes('/api/') | Programmatisches Logik-Matching |
route.abort() Anfragen abbrechen
Beispiel
// Analytics-Skripte wie Google Analytics blockieren
await page.route('**/*analytics*', route => route.abort());
// CSS-Dateien blockieren
await page.route('**/*.css', route => route.abort());
await page.goto('https://www.example.com/');
// Die Seite wird ohne Styles geladen, aber funktionale Tests sind nicht beeinträchtigt.
});
route.fulfill() Mock-Antworten
route.fulfill()Sie ist die leistungsstärkste Mock-Methode und kann jede benutzerdefinierte Antwort zurückgeben.
Mock-JSON-Daten
Beispiel
// Benutzerlisten-API abfangen und Mock-Daten zurückgeben
await page.route('**/api/users', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
json: [
{ id: 1, name: 'example_user', email: '[email protected]' },
{ id: 2, name: 'test_user', email: '[email protected]' },
],
});
});
await page.goto('https://www.example.com/users');
// Die Seite zeigt Mock-Daten anstelle echter API-Daten an
});
Mock-Fehlerantworten
Beispiel
// Simuliere einen 500-Serverfehler
await page.route('**/api/data', async route => {
await route.fulfill({
status: 500,
contentType: 'application/json',
json: { error: 'Internal server error' },
});
});
await page.goto('https://www.example.com/dashboard');
// Überprüfe, ob die Fehlermeldung korrekt angezeigt wird
await expect(page.getByText('Internal server error')).toBeVisible();
});
route.continue() Ändern und Fortfahren
Anstatt direkt Mock-Daten zurückzugeben, ändert es die echte Anfrage oder Antwort und sendet sie dann weiter an den Server.
Beispiel
await page.route('**/api/**', async (route, request) => {
// Anfrage-Header ändern und benutzerdefinierte Header hinzufügen
const headers = {
...Anfrage-.Header(),
'X-Custom-Header': 'EXAMPLE-TEST',
};
await route.continue({ headers });
});
await page.goto('https://www.example.com/');
});
test('POST-Daten ändern', async ({ page }) => {
await page.route('**/api/login', async (route, request) => {
// Den Body von POST-Anfragen überschreiben
const postData = JSON.parse(request.postData() || '{}');
postData.mode = 'test'; // Testmarkierung hinzufügen
await route.continue({
postData: JSON.stringify(postData),
});
});
});
route.fetch() Echte Anfragen
In der Mock-Handler-Funktion kannst duroute.fetch()um die Anfrage tatsächlich zu senden, die echte Antwort zu erhalten und sie dann zu ändern.
Beispiel
await page.route('**/api/products', async route => {
// Zuerst die echte Antwort abrufen
const response = await route.fetch();
const body = await response.json();
// Die Antwortdaten ändern
body.items[0].name = 'BEISPIEL geänderter Produktname';
// Die geänderten Daten zurückgeben
await route.fulfill({
status: response.status(),
contentType: 'application/json',
json: body,
});
});
});
Abfangen auf Kontextebene vs. Abfangen auf Seitenebene
| Methode | Geltungsbereich | Anwendungsfälle |
|---|---|---|
page.route() | Nur die aktuelle Seite | Netzwerk-Mock für eine einzelne Seite |
context.route() | Alle Seiten in diesem Kontext | Mock-Regeln, die von mehreren Seiten gemeinsam genutzt werden |
Beispiel
// Im gesamten Kontext abfangen; gilt für alle Seiten
await context.route('**/*.css', route => route.abort());
});
test('Test 1', async ({ page }) => { /* Kein CSS */ });
test('Test 2', async ({ page }) => { /* Kein CSS */ });
Aufzeichnung und Wiedergabe von HAR-Dateien
Eine HAR-Datei (HTTP Archive) zeichnet alle Netzwerkanfragen einer Seite auf und kann sie anschließend wiedergeben oder mocken.
Beispiel
// Netzwerkaufzeichnungen aus der HAR-Datei laden und wiedergeben
await page.routeFromHAR('tests/hars/api-responses.har');
await page.goto('https://www.example.com/');
// Alle passenden Anfragen erhalten Antworten aus der HAR-Datei
});
# 录制 HAR 文件 npx playwright open --save-har=tests/hars/api-responses.har https://www.example.com/
Andere ErweiterungenHAR-Dateien eignen sich zum Mocken großer oder komplexer API-Antworten. Einmal aufzeichnen, und nachfolgende Tests spielen aus der HAR-Datei ab, ohne von einem echten Server abhängig zu sein.