Học Playwright tiếng Việt, Cộng đồng Playwright cho người Việt

Vọc Vạch Playwright

[Vọc Playwright] Retries

https://playwright.dev/docs/test-retries

Giới thiệu

  • Test retry là cách mà test tự động chạy lại khi nó fail.
  • Test retry sẽ rất hữu ích trong trường hợp bạn có một số test không ổn định (flaky).
  • Test retry được cấu hình trong file config (playwright.config.ts)

Failures

  • Playwright test chạy test trên các worker process. Các process này chính là OS processes, chạy độc lập, được điều phối bởi test runner.

  • Tất cả các worker đều có môi trường độc lập và có browser riêng.

  • Cùng xét đoạn code dưới đây:

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 () => { /* ... */ });
});
  • Khi tất cả cá test pass, thứ tự chạy sẽ giống nhau ở tất cả các worker:
    • beforeAll hook
    • first good test
    • second flaky test
    • third good test
    • afterAll hook
  • Nếu có một test fail, quá trình này sẽ được thực hiện như sau:
    • Stop worker hiện tại.
    • Tạo một worker mới, tiếp tục chạy các test fail.
      • Vì tạo worker mới nên các hook before, after cũng sẽ được chạy lại.
  • Xét vụ dụ sau:
    • Worker #1 chạy
      • beforeAll hook
      • first good pass
      • second flaky fail
      • afterAll hook runs
    • Worker #2 chạy
      • beforeAll hook
      • third good pass
      • afterAll hook runs
  • Nếu bạn enable retry lên, worker số 2 sẽ chạy lại test bị fail và bắt đầu từ đây:
    • Worker #1 chạy
      • beforeAll hook
      • first good pass
      • second flaky fail
      • afterAll hook runs
    • Worker #2 chạy
      • beforeAll hook
      • second flaky pass
      • third good pass
      • afterAll hook runs

Retries

  • Bạn có thể cấu hình số lần retry thông qua terminal:
# Give failing tests 3 retry attempts
npx playwright test --retries=3
  • Hay thông qua config
import { defineConfig } from '@playwright/test';

export default defineConfig({
  // Give failing tests 3 retry attempts
  retries: 3,
});
  • Playwright phân loại các test thành 3 loại:

    • passed: test chạy pass
    • flaky: test chạy fail lần đầu, nhưng retry lại thì pass.
    • failed: test chạy fail.
  • Ví dụ

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)
  • Bạn có thể xác định được retry thông qua testInfo.retry, có thể access được ở ở test, hook, hay fixture. Ví dụ:
import { test, expect } from '@playwright/test';

test('my test', async ({ page }, testInfo) => {
  if (testInfo.retry)
    await cleanSomeCachesOnTheServer();
  // ...
});
  • Bạn cũng có thể cấu hình retry cho một danh sách các test, sử dụng test.descritbe.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 }) => {
    // ...
  });
});

Serial mode

  • Sử dụng test.describe.serial() để nhóm các test lại và đảm bảo các test sẽ luôn được chạy cùng nhau và theo thứ tự.
  • Nếu một test fail, tòan bộ các test còn lại sẽ bị skip.
  • Thử xét ví dụ bạn có test dưới đây:
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 }) => { /* ... */ });
  • Khi chạy test không có retry, nếu một test fail thì các test phía sau sẽ bị skip hết.

    • Worker #1 chạy
      • beforeAll hook
      • first good pass
      • second flaky fail
      • third good sẽ bị skip
  • Khi có retry, test sẽ được retry cùng nhau:

    • Worker #1 chạy
      • beforeAll hook
      • first good pass
      • second flaky fail
      • third good sẽ bị skip
    • Worker #2 chạy
      • beforeAll hook chạy lại
      • first good pass
      • second flaky pass
      • third good pass
  • Lưu ý: bạn vẫn nên viết các test độc lập nhau thì hơn. Chạy vừa nhanh, mà lúc retry cũng độc lập nữa.

Reuse single page giữa các test

  • Mặc định là playwright sẽ sử dụng các page khác nhau cho mỗi test.
  • Trường hợp bạn muốn dùng lại, hãy khai báo ở bên ngoài test và dùng lại bên trong.
  • Ví dụ dưới đây khai báo biến page ở trong khối describe, trong beforeAll khởi tạo cho biến page, và dùng lại ở trong các test
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();
});

Trả lời