Skip to main content

測試重試

簡介

測試重試是一種在測試失敗時自動重新執行測試的方法。當測試不穩定並間歇性失敗時,這很有用。測試重試在組態設定檔案中組態設定。

失敗

Playwright Test 在工作程序中執行測試。這些程序是作業系統程序,獨立執行,由測試執行器協調。所有工作程序都有相同的環境,每個都啟動自己的瀏覽器。

考慮以下程式碼片段:

import { test } from '@playwright/test';

test.describe('suite', () => {
test.beforeAll(async () => { /* ... */ });
test('first good', async ({ page }) => { /* ... */ });
test('second flaky', async ({ page }) => { /* ... */ });
test('third good', async ({ page }) => { /* ... */ });
test.afterAll(async () => { /* ... */ });
});

所有測試通過時,它們將在同一工作程序中按順序執行。

  • 工作程序啟動
    • beforeAll 掛勾執行
    • first good 通過
    • second flaky 通過
    • third good 通過
    • afterAll 掛勾執行

如果任何測試失敗,Playwright Test 將丟棄整個工作程序以及瀏覽器,並啟動一個新的。測試將在新的工作程序中繼續,從下一個測試開始。

  • Worker process #1 starts
    • beforeAll hook runs
    • first good passes
    • second flaky fails
    • afterAll hook runs
  • Worker process #2 starts
    • beforeAll hook runs again
    • third good passes
    • afterAll hook runs

如果您啟用重試,第二個工作程序將開始重試失敗的測試並從那裡繼續。

  • 工作程序 #1 啟動
    • beforeAll 掛勾執行
    • first good 通過
    • second flaky 失敗
    • afterAll 掛勾執行
  • 工作程序 #2 啟動
    • beforeAll 掛勾再次執行
    • second flaky 被重試並通過
    • third good 通過
    • afterAll 掛勾執行

這種機制對於獨立測試非常有效,並保證失敗的測試不會影響健康的測試。

重試

Playwright 支援測試重試。啟用時,失敗的測試將被多次重試,直到它們通過,或直到達到最大重試次數。預設情況下,失敗的測試不會重試。

# Give failing tests 3 retry attempts
npx playwright test --retries=3

您可以在組態設定檔案中設定重試次數:

playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
// Give failing tests 3 retry attempts
retries: 3,
});

Playwright Test 會將測試分類如下:

  • "passed" - 第一次執行就通過的測試;
  • "flaky" - 第一次執行失敗,但重試時通過的測試;
  • "failed" - 第一次執行失敗且所有重試都失敗的測試。
Running 3 tests using 1 worker

✓ example.spec.ts:4:2 › first passes (438ms)
x example.spec.ts:5:2 › second flaky (691ms)
✓ example.spec.ts:5:2 › second flaky (522ms)
✓ example.spec.ts:6:2 › third passes (932ms)

1 flaky
example.spec.ts:5:2 › second flaky
2 passed (4s)

您可以在執行時使用 testInfo.retry 檢測重試,它可以在任何測試、掛勾或佈置中存取。以下是在重試前清除一些伺服器端狀態的範例。

import { test, expect } from '@playwright/test';

test('my test', async ({ page }, testInfo) => {
if (testInfo.retry)
await cleanSomeCachesOnTheServer();
// ...
});

您可以使用 test.describe.configure() 為特定的測試群組或單一檔案指定重試次數。

import { test, expect } from '@playwright/test';

test.describe(() => {
// All tests in this describe group will get 2 retry attempts.
test.describe.configure({ retries: 2 });

test('test 1', async ({ page }) => {
// ...
});

test('test 2', async ({ page }) => {
// ...
});
});

序列模式

使用 test.describe.serial() 將相依的測試分組,以確保它們總是一起按順序執行。如果其中一個測試失敗,所有後續的測試都會被跳過。群組中的所有測試會一起重試。

考慮以下使用 test.describe.serial 的程式碼片段:

import { test } from '@playwright/test';

test.describe.configure({ mode: 'serial' });

test.beforeAll(async () => { /* ... */ });
test('first good', async ({ page }) => { /* ... */ });
test('second flaky', async ({ page }) => { /* ... */ });
test('third good', async ({ page }) => { /* ... */ });

在沒有重試的情況下執行時,失敗後的所有測試都會被跳過:

  • 工作程序 #1:
    • beforeAll 掛勾執行
    • first good 通過
    • second flaky 失敗
    • third good 完全被跳過

在有重試的情況下執行時,所有測試會一起重試:

  • 工作程序 #1:
    • beforeAll 掛勾執行
    • first good 通過
    • second flaky 失敗
    • third good 被跳過
  • 工作程序 #2:
    • beforeAll 掛勾再次執行
    • first good 再次通過
    • second flaky 通過
    • third good 通過
note

通常最好讓您的測試獨立,這樣它們可以有效地執行和獨立重試。

在測試之間重複使用單一頁面

Playwright Test 為每個測試建立一個獨立的 Page 物件。然而,如果您想在多個測試之間重複使用單一 Page 物件,您可以在 test.beforeAll() 中建立自己的頁面,並在 test.afterAll() 中關閉它。

example.spec.ts
import { test, type Page } from '@playwright/test';

test.describe.configure({ mode: 'serial' });

let page: Page;

test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
});

test.afterAll(async () => {
await page.close();
});

test('runs first', async () => {
await page.goto('https://playwright.dev/');
});

test('runs second', async () => {
await page.getByText('Get Started').click();
});