跳到主要內容

Playwright 測試

Playwright Test 提供了 test 函數來宣告測試,以及 expect 函數來編寫斷言。

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

test('basic test', async ({ page }) => {
await page.goto('https://playwright.dev.org.tw/');
const name = await page.innerText('.navbar__title');
expect(name).toBe('Playwright');
});

方法

test

新增於:v1.10 test.test

宣告一個測試。

  • test(標題,主體)
  • test(標題,詳細資訊,主體)

用法

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

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

標籤

您可以透過提供額外的測試詳細資訊來標記測試。或者,您可以在測試標題中包含標籤。請注意,每個標籤都必須以 @ 符號開頭。

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

test('basic test', {
tag: '@smoke',
}, async ({ page }) => {
await page.goto('https://playwright.dev.org.tw/');
// ...
});

test('another test @smoke', async ({ page }) => {
await page.goto('https://playwright.dev.org.tw/');
// ...
});

測試標籤會顯示在測試報告中,並且可透過 TestCase.tags 屬性提供給自訂報告器。

您也可以在測試執行期間依標籤篩選測試

深入瞭解標記

註解

您可以透過提供額外的測試詳細資訊來註解測試。

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

test('basic test', {
annotation: {
type: 'issue',
description: 'https://github.com/microsoft/playwright/issues/23180',
},
}, async ({ page }) => {
await page.goto('https://playwright.dev.org.tw/');
// ...
});

測試註解會顯示在測試報告中,並且可透過 TestCase.annotations 屬性提供給自訂報告器。

您也可以在執行期間透過操作 testInfo.annotations 來新增註解。

深入瞭解測試註解

引數


test.afterAll

新增於:v1.10 test.test.afterAll

宣告一個 afterAll 鉤子,該鉤子在所有測試之後每個 worker 執行一次。

當在測試檔案的範圍內呼叫時,會在檔案中所有測試之後執行。當在 test.describe() 群組內呼叫時,會在群組中所有測試之後執行。

用法

test.afterAll(async () => {
console.log('Done with tests');
// ...
});

或者,您可以宣告一個帶有標題的鉤子。

test.afterAll('Teardown', async () => {
console.log('Done with tests');
// ...
});

引數

  • title string (選用)新增於:v1.38#

    鉤子標題。

  • hookFunction function(Fixtures, TestInfo)#

    鉤子函數,它接受一或兩個引數:一個包含 worker 夾具的物件和選用的 TestInfo

詳細資訊

當新增多個 afterAll 鉤子時,它們將按照註冊順序執行。

請注意,worker 進程會在測試失敗時重新啟動,並且 afterAll 鉤子會在新的 worker 中再次執行。深入瞭解worker 和失敗

即使某些鉤子失敗,Playwright 也會繼續執行所有適用的鉤子。

  • test.afterAll(hookFunction)
  • test.afterAll(標題,hookFunction)

test.afterEach

新增於:v1.10 test.test.afterEach

宣告一個 afterEach 鉤子,該鉤子在每個測試之後執行。

當在測試檔案的範圍內呼叫時,會在檔案中每個測試之後執行。當在 test.describe() 群組內呼叫時,會在群組中每個測試之後執行。

您可以存取與測試主體本身相同的所有夾具,以及提供許多有用資訊的 TestInfo 物件。例如,您可以檢查測試是成功還是失敗。

  • test.afterEach(hookFunction)
  • test.afterEach(標題,hookFunction)

用法

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

test.afterEach(async ({ page }) => {
console.log(`Finished ${test.info().title} with status ${test.info().status}`);

if (test.info().status !== test.info().expectedStatus)
console.log(`Did not run as expected, ended up at ${page.url()}`);
});

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

或者,您可以宣告一個帶有標題的鉤子。

example.spec.ts
test.afterEach('Status check', async ({ page }) => {
if (test.info().status !== test.info().expectedStatus)
console.log(`Did not run as expected, ended up at ${page.url()}`);
});

引數

詳細資訊

當新增多個 afterEach 鉤子時,它們將按照註冊順序執行。

即使某些鉤子失敗,Playwright 也會繼續執行所有適用的鉤子。


test.beforeAll

新增於:v1.10 test.test.beforeAll

宣告一個 beforeAll 鉤子,該鉤子在所有測試之前每個 worker 進程執行一次。

當在測試檔案的範圍內呼叫時,會在檔案中所有測試之前執行。當在 test.describe() 群組內呼叫時,會在群組中所有測試之前執行。

您可以使用 test.afterAll() 來拆解在 beforeAll 中設定的任何資源。

  • test.beforeAll(hookFunction)
  • test.beforeAll(標題,hookFunction)

用法

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

test.beforeAll(async () => {
console.log('Before tests');
});

test.afterAll(async () => {
console.log('After tests');
});

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

或者,您可以宣告一個帶有標題的鉤子。

example.spec.ts
test.beforeAll('Setup', async () => {
console.log('Before tests');
});

引數

  • title string (選用)新增於:v1.38#

    鉤子標題。

  • hookFunction function(Fixtures, TestInfo)#

    鉤子函數,它接受一或兩個引數:一個包含 worker 夾具的物件和選用的 TestInfo

詳細資訊

當新增多個 beforeAll 鉤子時,它們將按照註冊順序執行。

請注意,worker 進程會在測試失敗時重新啟動,並且 beforeAll 鉤子會在新的 worker 中再次執行。深入瞭解worker 和失敗

即使某些鉤子失敗,Playwright 也會繼續執行所有適用的鉤子。


test.beforeEach

新增於:v1.10 test.test.beforeEach

宣告一個 beforeEach 鉤子,該鉤子在每個測試之前執行。

當在測試檔案的範圍內呼叫時,會在檔案中每個測試之前執行。當在 test.describe() 群組內呼叫時,會在群組中每個測試之前執行。

您可以存取與測試主體本身相同的所有夾具,以及提供許多有用資訊的 TestInfo 物件。例如,您可以在開始測試之前導覽頁面。

您可以使用 test.afterEach() 來拆解在 beforeEach 中設定的任何資源。

  • test.beforeEach(hookFunction)
  • test.beforeEach(標題,hookFunction)

用法

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

test.beforeEach(async ({ page }) => {
console.log(`Running ${test.info().title}`);
await page.goto('https://my.start.url/');
});

test('my test', async ({ page }) => {
expect(page.url()).toBe('https://my.start.url/');
});

或者,您可以宣告一個帶有標題的鉤子。

example.spec.ts
test.beforeEach('Open start URL', async ({ page }) => {
console.log(`Running ${test.info().title}`);
await page.goto('https://my.start.url/');
});

引數

詳細資訊

當新增多個 beforeEach 鉤子時,它們將按照註冊順序執行。

即使某些鉤子失敗,Playwright 也會繼續執行所有適用的鉤子。


test.describe

新增於:v1.10 test.test.describe

宣告一組測試。

  • test.describe(標題,callback)
  • test.describe(callback)
  • test.describe(標題,詳細資訊,callback)

用法

您可以宣告一組帶有標題的測試。標題將在測試報告中顯示為每個測試標題的一部分。

test.describe('two tests', () => {
test('one', async ({ page }) => {
// ...
});

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

匿名群組

您也可以宣告一個沒有標題的測試群組。這對於使用 test.use() 為一組測試提供通用選項非常方便。

test.describe(() => {
test.use({ colorScheme: 'dark' });

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

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

標籤

您可以透過提供額外的詳細資訊來標記群組中的所有測試。請注意,每個標籤都必須以 @ 符號開頭。

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

test.describe('two tagged tests', {
tag: '@smoke',
}, () => {
test('one', async ({ page }) => {
// ...
});

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

深入瞭解標記

註解

您可以透過提供額外的詳細資訊來註解群組中的所有測試。

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

test.describe('two annotated tests', {
annotation: {
type: 'issue',
description: 'https://github.com/microsoft/playwright/issues/23180',
},
}, () => {
test('one', async ({ page }) => {
// ...
});

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

深入瞭解測試註解

引數


test.describe.configure

新增於:v1.10 test.test.describe.configure

組態封閉範圍。可以在最上層或 describe 內部執行。組態適用於整個範圍,無論它是在測試宣告之前還是之後執行。

深入瞭解執行模式此處

用法

  • 平行執行測試。

    // Run all the tests in the file concurrently using parallel workers.
    test.describe.configure({ mode: 'parallel' });
    test('runs in parallel 1', async ({ page }) => {});
    test('runs in parallel 2', async ({ page }) => {});
  • 循序執行測試,從頭開始重試。

    注意

    不建議循序執行。通常最好讓您的測試隔離,以便它們可以獨立執行。

    // Annotate tests as inter-dependent.
    test.describe.configure({ mode: 'serial' });
    test('runs first', async ({ page }) => {});
    test('runs second', async ({ page }) => {});
  • 為每個測試組態重試和逾時。

    // Each test in the file will be retried twice and have a timeout of 20 seconds.
    test.describe.configure({ retries: 2, timeout: 20_000 });
    test('runs first', async ({ page }) => {});
    test('runs second', async ({ page }) => {});
  • 平行執行多個 describe,但依序執行每個 describe 內部的測試。

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

    test.describe('A, runs in parallel with B', () => {
    test.describe.configure({ mode: 'default' });
    test('in order A1', async ({ page }) => {});
    test('in order A2', async ({ page }) => {});
    });

    test.describe('B, runs in parallel with A', () => {
    test.describe.configure({ mode: 'default' });
    test('in order B1', async ({ page }) => {});
    test('in order B2', async ({ page }) => {});
    });

引數

  • options Object (選用)
    • mode "default" | "parallel" | "serial" (選用)#

      執行模式。深入瞭解執行模式此處

    • retries number (選用)新增於:v1.28#

      每個測試的重試次數。

    • timeout number (選用)新增於:v1.28#

      每個測試的逾時時間,以毫秒為單位。覆寫 testProject.timeouttestConfig.timeout


test.describe.fixme

新增於:v1.25 test.test.describe.fixme

宣告一個測試群組,類似於 test.describe()。此群組中的測試標記為「fixme」且不會執行。

  • test.describe.fixme(標題,callback)
  • test.describe.fixme(callback)
  • test.describe.fixme(標題,詳細資訊,callback)

用法

test.describe.fixme('broken tests that should be fixed', () => {
test('example', async ({ page }) => {
// This test will not run
});
});

您也可以省略標題。

test.describe.fixme(() => {
// ...
});

引數


test.describe.only

新增於:v1.10 test.test.describe.only

宣告一個焦點測試群組。如果有一些焦點測試或套件,它們都會執行,但其他任何測試都不會執行。

  • test.describe.only(標題,callback)
  • test.describe.only(callback)
  • test.describe.only(標題,詳細資訊,callback)

用法

test.describe.only('focused group', () => {
test('in the focused group', async ({ page }) => {
// This test will run
});
});
test('not in the focused group', async ({ page }) => {
// This test will not run
});

您也可以省略標題。

test.describe.only(() => {
// ...
});

引數


test.describe.skip

新增於:v1.10 test.test.describe.skip

宣告一個跳過的測試群組,類似於 test.describe()。跳過的群組中的測試永遠不會執行。

  • test.describe.skip(標題,callback)
  • test.describe.skip(標題)
  • test.describe.skip(標題,詳細資訊,callback)

用法

test.describe.skip('skipped group', () => {
test('example', async ({ page }) => {
// This test will not run
});
});

您也可以省略標題。

test.describe.skip(() => {
// ...
});

引數


test.extend

新增於:v1.10 test.test.extend

透過定義可用於測試的夾具和/或選項來擴充 test 物件。

用法

首先定義夾具和/或選項。

import { test as base } from '@playwright/test';
import { TodoPage } from './todo-page';

export type Options = { defaultItem: string };

// Extend basic test by providing a "defaultItem" option and a "todoPage" fixture.
export const test = base.extend<Options & { todoPage: TodoPage }>({
// Define an option and provide a default value.
// We can later override it in the config.
defaultItem: ['Do stuff', { option: true }],

// Define a fixture. Note that it can use built-in fixture "page"
// and a new option "defaultItem".
todoPage: async ({ page, defaultItem }, use) => {
const todoPage = new TodoPage(page);
await todoPage.goto();
await todoPage.addToDo(defaultItem);
await use(todoPage);
await todoPage.removeAll();
},
});

然後在測試中使用夾具。

example.spec.ts
import { test } from './my-test';

test('test 1', async ({ todoPage }) => {
await todoPage.addToDo('my todo');
// ...
});

在組態檔中組態選項。

playwright.config.ts
import { defineConfig } from '@playwright/test';
import type { Options } from './my-test';

export default defineConfig<Options>({
projects: [
{
name: 'shopping',
use: { defaultItem: 'Buy milk' },
},
{
name: 'wellbeing',
use: { defaultItem: 'Exercise!' },
},
]
});

深入瞭解夾具參數化測試

引數

傳回


test.fail

新增於:v1.10 test.test.fail

將測試標記為「應該失敗」。Playwright 執行此測試並確保它實際上失敗。這對於文件目的很有用,以確認某些功能已損壞,直到修復為止。

宣告一個「失敗」測試

  • test.fail(標題,主體)
  • test.fail(標題,詳細資訊,主體)

在執行期間將測試註解為「失敗」

  • test.fail(條件,描述)
  • test.fail(callback,描述)
  • test.fail()

用法

您可以宣告一個測試為失敗,以便 Playwright 確保它實際上失敗。

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

test.fail('not yet ready', async ({ page }) => {
// ...
});

如果您的測試在某些組態中失敗,但並非全部失敗,您可以根據某些條件在測試主體內將測試標記為失敗。我們建議在這種情況下傳遞 description 引數。

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

test('fail in WebKit', async ({ page, browserName }) => {
test.fail(browserName === 'webkit', 'This feature is not implemented for Mac yet');
// ...
});

您可以使用單個 test.fail(callback, description) 呼叫,根據某些條件將檔案或 test.describe() 群組中的所有測試標記為「應該失敗」。

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

test.fail(({ browserName }) => browserName === 'webkit', 'not implemented yet');

test('fail in WebKit 1', async ({ page }) => {
// ...
});
test('fail in WebKit 2', async ({ page }) => {
// ...
});

您也可以在測試主體內呼叫不帶引數的 test.fail(),以始終將測試標記為失敗。我們建議改用 test.fail(title, body) 宣告失敗的測試。

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

test('less readable', async ({ page }) => {
test.fail();
// ...
});

引數

  • title string (選用)新增於:v1.42#

    測試標題。

  • details Object (選用)新增於:v1.42#

    請參閱 test() 以取得測試詳細資訊描述。

  • body function(Fixtures, TestInfo) (選用)新增於:v1.42#

    測試主體,它接受一或兩個引數:一個包含夾具的物件和選用的 TestInfo

  • condition boolean (選用)#

    當條件為 true 時,測試標記為「應該失敗」。

  • callback function(Fixtures):boolean (選用)#

    一個函數,用於根據測試夾具傳回是否標記為「應該失敗」。當傳回值為 true 時,測試或多個測試會標記為「應該失敗」。

  • description string (選用)#

    選用的描述,將反映在測試報告中。


test.fail.only

新增於:v1.49 test.test.fail.only

您可以使用 test.fail.only 將焦點放在預期會失敗的特定測試上。這在偵錯失敗的測試或處理特定問題時特別有用。

宣告一個焦點「失敗」測試

  • test.fail.only(標題,主體)
  • test.fail.only(標題,詳細資訊,主體)

用法

您可以宣告一個焦點失敗測試,以便 Playwright 只執行此測試並確保它實際上失敗。

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

test.fail.only('focused failing test', async ({ page }) => {
// This test is expected to fail
});
test('not in the focused group', async ({ page }) => {
// This test will not run
});

引數


test.fixme

新增於:v1.10 test.test.fixme

將測試標記為「fixme」,目的是要修復它。Playwright 將不會執行超過 test.fixme() 呼叫的測試。

宣告一個「fixme」測試

  • test.fixme(標題,主體)
  • test.fixme(標題,詳細資訊,主體)

在執行期間將測試註解為「fixme」

  • test.fixme(條件,描述)
  • test.fixme(callback,描述)
  • test.fixme()

用法

您可以宣告一個要修復的測試,Playwright 將不會執行它。

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

test.fixme('to be fixed', async ({ page }) => {
// ...
});

如果您的測試應該在某些組態中修復,但並非全部修復,您可以根據某些條件在測試主體內將測試標記為「fixme」。我們建議在這種情況下傳遞 description 引數。Playwright 將執行測試,但在 test.fixme 呼叫後立即中止它。

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

test('to be fixed in Safari', async ({ page, browserName }) => {
test.fixme(browserName === 'webkit', 'This feature breaks in Safari for some reason');
// ...
});

您可以使用單個 test.fixme(callback, description) 呼叫,根據某些條件將檔案或 test.describe() 群組中的所有測試標記為「fixme」。

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

test.fixme(({ browserName }) => browserName === 'webkit', 'Should figure out the issue');

test('to be fixed in Safari 1', async ({ page }) => {
// ...
});
test('to be fixed in Safari 2', async ({ page }) => {
// ...
});

您也可以在測試主體內呼叫不帶引數的 test.fixme(),以始終將測試標記為失敗。我們建議改用 test.fixme(title, body)

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

test('less readable', async ({ page }) => {
test.fixme();
// ...
});

引數

  • title string (選用)#

    測試標題。

  • details Object (選用)新增於:v1.42#

    請參閱 test() 以取得測試詳細資訊描述。

  • body function(Fixtures, TestInfo) (選用)#

    測試主體,它接受一或兩個引數:一個包含夾具的物件和選用的 TestInfo

  • condition boolean (選用)#

    當條件為 true 時,測試標記為「應該失敗」。

  • callback function(Fixtures):boolean (選用)#

    一個函數,用於根據測試夾具傳回是否標記為「應該失敗」。當傳回值為 true 時,測試或多個測試會標記為「應該失敗」。

  • description string (選用)#

    選用的描述,將反映在測試報告中。


test.info

新增於:v1.10 test.test.info

傳回有關目前正在執行的測試的資訊。此方法只能在測試執行期間呼叫,否則會擲回錯誤。

用法

test('example test', async ({ page }) => {
// ...
await test.info().attach('screenshot', {
body: await page.screenshot(),
contentType: 'image/png',
});
});

傳回


test.only

新增於:v1.10 test.test.only

宣告一個焦點測試。如果有一些焦點測試或套件,它們都會執行,但其他任何測試都不會執行。

  • test.only(標題,主體)
  • test.only(標題,詳細資訊,主體)

用法

test.only('focus this test', async ({ page }) => {
// Run only focused tests in the entire project.
});

引數


test.setTimeout

新增於:v1.10 test.test.setTimeout

變更測試的逾時時間。零表示沒有逾時。深入瞭解各種逾時

目前正在執行的測試的逾時時間可透過 testInfo.timeout 取得。

用法

  • 變更測試逾時時間。

    test('very slow test', async ({ page }) => {
    test.setTimeout(120000);
    // ...
    });
  • 從緩慢的 beforeEach 鉤子變更逾時時間。請注意,這會影響與 beforeEach 鉤子共用的測試逾時時間。

    test.beforeEach(async ({ page }, testInfo) => {
    // Extend timeout for all tests running this hook by 30 seconds.
    test.setTimeout(testInfo.timeout + 30000);
    });
  • 變更 beforeAllafterAll 鉤子的逾時時間。請注意,這會影響鉤子的逾時時間,而不是測試逾時時間。

    test.beforeAll(async () => {
    // Set timeout for this hook.
    test.setTimeout(60000);
    });
  • 變更 test.describe() 群組中所有測試的逾時時間。

    test.describe('group', () => {
    // Applies to all tests in this group.
    test.describe.configure({ timeout: 60000 });

    test('test one', async () => { /* ... */ });
    test('test two', async () => { /* ... */ });
    test('test three', async () => { /* ... */ });
    });

引數

  • timeout number#

    逾時時間,以毫秒為單位。


test.skip

新增於:v1.10 test.test.skip

跳過測試。Playwright 將不會執行超過 test.skip() 呼叫的測試。

跳過的測試不應該永遠執行。如果您打算修復測試,請改用 test.fixme()

宣告一個跳過的測試

  • test.skip(標題,主體)
  • test.skip(標題,詳細資訊,主體)

在執行期間跳過測試

  • test.skip(條件,描述)
  • test.skip(callback,描述)
  • test.skip()

用法

您可以宣告一個跳過的測試,Playwright 將不會執行它。

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

test.skip('never run', async ({ page }) => {
// ...
});

如果您的測試應該在某些組態中跳過,但並非全部跳過,您可以根據某些條件在測試主體內跳過測試。我們建議在這種情況下傳遞 description 引數。Playwright 將執行測試,但在 test.skip 呼叫後立即中止它。

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

test('Safari-only test', async ({ page, browserName }) => {
test.skip(browserName !== 'webkit', 'This feature is Safari-only');
// ...
});

您可以使用單個 test.skip(callback, description) 呼叫,根據某些條件跳過檔案或 test.describe() 群組中的所有測試。

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

test.skip(({ browserName }) => browserName !== 'webkit', 'Safari-only');

test('Safari-only test 1', async ({ page }) => {
// ...
});
test('Safari-only test 2', async ({ page }) => {
// ...
});

您也可以在測試主體內呼叫不帶引數的 test.skip(),以始終將測試標記為失敗。我們建議改用 test.skip(title, body)

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

test('less readable', async ({ page }) => {
test.skip();
// ...
});

引數

  • title string (選用)#

    測試標題。

  • details Object (選用)新增於:v1.42#

    請參閱 test() 以取得測試詳細資訊描述。

  • body function(Fixtures, TestInfo) (選用)#

    測試主體,它接受一或兩個引數:一個包含夾具的物件和選用的 TestInfo

  • condition boolean (選用)#

    當條件為 true 時,測試標記為「應該失敗」。

  • callback function(Fixtures):boolean (選用)#

    一個函數,用於根據測試夾具傳回是否標記為「應該失敗」。當傳回值為 true 時,測試或多個測試會標記為「應該失敗」。

  • description string (選用)#

    選用的描述,將反映在測試報告中。


test.slow

新增於:v1.10 test.test.slow

將測試標記為「slow」。Slow 測試將獲得三倍的預設逾時時間。

請注意,test.slow() 無法在 beforeAllafterAll 鉤子中使用。請改用 test.setTimeout()

  • test.slow()
  • test.slow(條件,描述)
  • test.slow(callback,描述)

用法

您可以透過在測試主體內呼叫 test.slow() 將測試標記為 slow。

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

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

如果您的測試在某些組態中 slow,但並非全部 slow,您可以根據條件將其標記為 slow。我們建議在這種情況下傳遞 description 引數。

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

test('slow in Safari', async ({ page, browserName }) => {
test.slow(browserName === 'webkit', 'This feature is slow in Safari');
// ...
});

您可以透過傳遞回呼,根據某些條件將檔案或 test.describe() 群組中的所有測試標記為「slow」。

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

test.slow(({ browserName }) => browserName === 'webkit', 'all tests are slow in Safari');

test('slow in Safari 1', async ({ page }) => {
// ...
});
test('fail in Safari 2', async ({ page }) => {
// ...
});

引數

  • condition boolean (選填)#

    當 condition 為 true 時,測試會被標記為「slow」。

  • callback function(Fixtures):boolean (選填)#

    一個函式,根據測試夾具 (fixtures) 回傳是否標記為「slow」。當回傳值為 true 時,測試或多個測試會被標記為「slow」。

  • description string (選填)#

    選用的描述,將反映在測試報告中。


test.step

新增於:v1.10 test.test.step

宣告一個會顯示在報告中的測試步驟。

用法

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

test('test', async ({ page }) => {
await test.step('Log in', async () => {
// ...
});

await test.step('Outer step', async () => {
// ...
// You can nest steps inside each other.
await test.step('Inner step', async () => {
// ...
});
});
});

引數

  • title string#

    步驟名稱。

  • body function():Promise<Object>#

    步驟主體。

  • options Object (選用)

    • box boolean (選填)新增於: v1.39#

      是否在報告中將步驟框起來。預設為 false。當步驟被框起來時,從步驟內部拋出的錯誤會指向步驟呼叫的位置。詳情請見下方說明。

    • location Location (選填)新增於: v1.48#

      指定步驟在測試報告和追蹤檢視器中顯示的自訂位置。預設情況下,會顯示 test.step() 呼叫的位置。

    • timeout number (選用)新增於: v1.50#

      步驟完成允許的最長時間,以毫秒為單位。如果步驟在指定的逾時時間內未完成,test.step() 方法將拋出 TimeoutError。預設值為 0 (無逾時)。

傳回

詳細資訊

此方法回傳步驟回呼函式所回傳的值。

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

test('test', async ({ page }) => {
const user = await test.step('Log in', async () => {
// ...
return 'john';
});
expect(user).toBe('john');
});

裝飾器 (Decorator)

您可以使用 TypeScript 方法裝飾器將方法轉換為步驟。每次呼叫裝飾過的方法都會在報告中顯示為一個步驟。

function step(target: Function, context: ClassMethodDecoratorContext) {
return function replacementMethod(...args: any) {
const name = this.constructor.name + '.' + (context.name as string);
return test.step(name, async () => {
return await target.call(this, ...args);
});
};
}

class LoginPage {
constructor(readonly page: Page) {}

@step
async login() {
const account = { username: 'Alice', password: 's3cr3t' };
await this.page.getByLabel('Username or email address').fill(account.username);
await this.page.getByLabel('Password').fill(account.password);
await this.page.getByRole('button', { name: 'Sign in' }).click();
await expect(this.page.getByRole('button', { name: 'View profile and more' })).toBeVisible();
}
}

test('example', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.login();
});

框線 (Boxing)

當步驟內部發生錯誤時,您通常會看到錯誤指向發生錯誤的確切動作。例如,考慮以下登入步驟:

async function login(page) {
await test.step('login', async () => {
const account = { username: 'Alice', password: 's3cr3t' };
await page.getByLabel('Username or email address').fill(account.username);
await page.getByLabel('Password').fill(account.password);
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page.getByRole('button', { name: 'View profile and more' })).toBeVisible();
});
}

test('example', async ({ page }) => {
await page.goto('https://github.com/login');
await login(page);
});
Error: Timed out 5000ms waiting for expect(locator).toBeVisible()
... error details omitted ...

8 | await page.getByRole('button', { name: 'Sign in' }).click();
> 9 | await expect(page.getByRole('button', { name: 'View profile and more' })).toBeVisible();
| ^
10 | });

如上所示,測試可能會失敗,錯誤指向步驟內部。如果您希望錯誤強調「login」步驟而不是其內部,請使用 box 選項。框線步驟內部的錯誤會指向步驟呼叫的位置。

async function login(page) {
await test.step('login', async () => {
// ...
}, { box: true }); // Note the "box" option here.
}
Error: Timed out 5000ms waiting for expect(locator).toBeVisible()
... error details omitted ...

14 | await page.goto('https://github.com/login');
> 15 | await login(page);
| ^
16 | });

您也可以為框線步驟建立 TypeScript 裝飾器,類似於上述的常規步驟裝飾器

function boxedStep(target: Function, context: ClassMethodDecoratorContext) {
return function replacementMethod(...args: any) {
const name = this.constructor.name + '.' + (context.name as string);
return test.step(name, async () => {
return await target.call(this, ...args);
}, { box: true }); // Note the "box" option here.
};
}

class LoginPage {
constructor(readonly page: Page) {}

@boxedStep
async login() {
// ....
}
}

test('example', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.login(); // <-- Error will be reported on this line.
});

test.step.skip

新增於: v1.50 test.test.step.skip

將測試步驟標記為「skip」以暫時停用其執行,這對於目前失敗且計劃在近期修復的步驟很有用。Playwright 將不會執行此步驟。

用法

您可以宣告一個被跳過的步驟,Playwright 將不會執行它。

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

test('my test', async ({ page }) => {
// ...
await test.step.skip('not yet ready', async () => {
// ...
});
});

引數

  • title string#

    步驟名稱。

  • body function():Promise<Object>#

    步驟主體。

  • options Object (選用)

    • box boolean (選填)#

      是否在報告中將步驟框起來。預設為 false。當步驟被框起來時,從步驟內部拋出的錯誤會指向步驟呼叫的位置。詳情請見下方說明。

    • location Location (選填)#

      指定步驟在測試報告和追蹤檢視器中顯示的自訂位置。預設情況下,會顯示 test.step() 呼叫的位置。

    • timeout number (選填)#

      步驟完成的最長時間,以毫秒為單位。預設值為 0 (無逾時)。

傳回


test.use

新增於:v1.10 test.test.use

指定在單個測試檔案或 test.describe() 群組中使用的選項或夾具 (fixtures)。最常用於設定選項,例如設定 locale 以配置 context 夾具。

用法

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

test.use({ locale: 'en-US' });

test('test with locale', async ({ page }) => {
// Default context and page have locale as specified
});

引數

詳細資訊

test.use 可以在全域範圍或 test.describe 內部呼叫。在 beforeEachbeforeAll 內部呼叫是錯誤的。

也可以透過提供函式來覆寫夾具 (fixture)。

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

test.use({
locale: async ({}, use) => {
// Read locale from some configuration file.
const locale = await fs.promises.readFile('test-locale', 'utf-8');
await use(locale);
},
});

test('test with locale', async ({ page }) => {
// Default context and page have locale as specified
});

屬性 (Properties)

test.expect

新增於:v1.10 test.test.expect

expect 函式可用於建立測試斷言。請參閱 測試斷言 以了解更多資訊。

用法

test('example', async ({ page }) => {
await test.expect(page).toHaveTitle('Title');
});

類型 (Type)


已棄用 (Deprecated)

test.describe.parallel

新增於:v1.10 test.test.describe.parallel
不建議使用

請參閱 test.describe.configure(),這是配置執行模式的建議方式。

宣告一組可以平行執行的測試。預設情況下,單個測試檔案中的測試會依序執行,但使用 test.describe.parallel() 允許它們平行執行。

  • test.describe.parallel(title, callback)
  • test.describe.parallel(callback)
  • test.describe.parallel(title, details, callback)

用法

test.describe.parallel('group', () => {
test('runs in parallel 1', async ({ page }) => {});
test('runs in parallel 2', async ({ page }) => {});
});

請注意,平行測試是在不同的程序中執行的,並且無法共享任何狀態或全域變數。每個平行測試都會執行所有相關的 hook。

您也可以省略標題。

test.describe.parallel(() => {
// ...
});

引數


test.describe.parallel.only

新增於:v1.10 test.test.describe.parallel.only
不建議使用

請參閱 test.describe.configure(),這是配置執行模式的建議方式。

宣告一組可以平行執行的焦點測試群組。這與 test.describe.parallel() 類似,但會聚焦 (focus) 該群組。如果有一些焦點測試或套件 (suites),則將執行所有這些測試和套件,但不會執行其他任何內容。

  • test.describe.parallel.only(title, callback)
  • test.describe.parallel.only(callback)
  • test.describe.parallel.only(title, details, callback)

用法

test.describe.parallel.only('group', () => {
test('runs in parallel 1', async ({ page }) => {});
test('runs in parallel 2', async ({ page }) => {});
});

您也可以省略標題。

test.describe.parallel.only(() => {
// ...
});

引數


test.describe.serial

新增於:v1.10 test.test.describe.serial
不建議使用

請參閱 test.describe.configure(),這是配置執行模式的建議方式。

宣告一組應始終依序執行的測試。如果其中一個測試失敗,則會跳過所有後續測試。群組中的所有測試都會一起重試。

注意

不建議使用 serial。通常最好使您的測試隔離,以便它們可以獨立執行。

  • test.describe.serial(title, callback)
  • test.describe.serial(title)
  • test.describe.serial(title, details, callback)

用法

test.describe.serial('group', () => {
test('runs first', async ({ page }) => {});
test('runs second', async ({ page }) => {});
});

您也可以省略標題。

test.describe.serial(() => {
// ...
});

引數


test.describe.serial.only

新增於:v1.10 test.test.describe.serial.only
不建議使用

請參閱 test.describe.configure(),這是配置執行模式的建議方式。

宣告一組應始終依序執行的焦點測試群組。如果其中一個測試失敗,則會跳過所有後續測試。群組中的所有測試都會一起重試。如果有一些焦點測試或套件 (suites),則將執行所有這些測試和套件,但不會執行其他任何內容。

注意

不建議使用 serial。通常最好使您的測試隔離,以便它們可以獨立執行。

  • test.describe.serial.only(title, callback)
  • test.describe.serial.only(title)
  • test.describe.serial.only(title, details, callback)

用法

test.describe.serial.only('group', () => {
test('runs first', async ({ page }) => {
});
test('runs second', async ({ page }) => {
});
});

您也可以省略標題。

test.describe.serial.only(() => {
// ...
});

引數