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

test('Alle Bildanfragen abfangen', async ({ page }) => {
  // 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:

MusterBeispielBeschreibung
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
Funktionurl => url.includes('/api/')Programmatisches Logik-Matching

route.abort() Anfragen abbrechen

Beispiel

test('Blockiere Analytics-Skripte von Drittanbietern', async ({ page }) => {
  // 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

test('Mock-Benutzerlisten-API', async ({ page }) => {
  // 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

test('API-Fehlerbehandlung testen', async ({ page }) => {
  // 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

test('Anfrage-Header ändern', async ({ page }) => {
  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

test('Die echte Antwort ändern', async ({ page }) => {
  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

MethodeGeltungsbereichAnwendungsfälle
page.route()Nur die aktuelle SeiteNetzwerk-Mock für eine einzelne Seite
context.route()Alle Seiten in diesem KontextMock-Regeln, die von mehreren Seiten gemeinsam genutzt werden

Beispiel

test.beforeEach(async ({ context }) => {
  // 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

test('HAR-Datei zum Mocken verwenden', async ({ page }) => {
  // 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/

HAR-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.

Andere Erweiterungen