Skip to main content

全域設定和拆除

簡介

有兩種方式可以配置全域設定和拆除:使用全域設定檔案並在配置中設定 globalSetup 或使用專案相依性。使用專案相依性時,您可以定義一個在所有其他專案之前執行的專案。這是推薦的方式,因為它與 Playwright 測試執行器整合得更好:您的 HTML 報告將包含全域設定,追蹤將被記錄,並且可以使用佈置。以下表格提供兩種方式的詳細比較。

功能專案相依性(推薦)globalSetup(配置選項)
在所有測試前執行✅ 是✅ 是
HTML 報告可見性✅ 顯示為獨立專案❌ 不顯示
追蹤記錄✅ 完整追蹤可用❌ 不支援
Playwright 佈置✅ 完全支援❌ 不支援
瀏覽器管理✅ 透過 browser 佈置❌ 透過 browserType.launch() 完全手動
平行性和重試✅ 透過標準配置支援❌ 不適用
headlesstestIdAttribute 等配置選項✅ 自動套用❌ 忽略

選項 1:專案相依性

專案相依性是需要在另一個專案的測試執行之前執行的專案列表。它們對於配置全域設定動作非常有用,以便一個專案依賴於此項目先執行。使用相依性允許全域設定產生追蹤和其他成品。

設定

首先我們新增一個名稱為 'setup db' 的新專案。然後我們給它一個 testProject.testMatch 屬性,以匹配名為 global.setup.ts 的檔案:

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

export default defineConfig({
testDir: './tests',
// ...
projects: [
{
name: 'setup db',
testMatch: /global\.setup\.ts/,
},
// {
// other project
// }
]
});

然後我們將 testProject.dependencies 屬性新增到依賴設定專案的專案中,並將我們在上一步中定義的相依性專案名稱傳入陣列中:

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

export default defineConfig({
testDir: './tests',
// ...
projects: [
{
name: 'setup db',
testMatch: /global\.setup\.ts/,
},
{
name: 'chromium with db',
use: { ...devices['Desktop Chrome'] },
dependencies: ['setup db'],
},
]
});

在此範例中,'chromium with db' 專案依賴於 'setup db' 專案。然後我們建立一個設定測試,儲存在專案的根層級(請注意,設定和拆除程式碼必須透過呼叫 test() 函式定義為常規測試):

tests/global.setup.ts
import { test as setup } from '@playwright/test';

setup('create new database', async ({ }) => {
console.log('creating new database...');
// 初始化資料庫
});
tests/menu.spec.ts
import { test, expect } from '@playwright/test';

test('menu', async ({ page }) => {
// 您依賴資料庫的測試
});

拆除

您可以透過在設定專案中新增 testProject.teardown 屬性來拆除您的設定。這將在所有相依專案執行完畢後執行。

首先,我們將 testProject.teardown 屬性新增到設定專案中,名稱為 'cleanup db',這是我們在上一步中給拆除專案的名稱:

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

export default defineConfig({
testDir: './tests',
// ...
projects: [
{
name: 'setup db',
testMatch: /global\.setup\.ts/,
teardown: 'cleanup db',
},
{
name: 'cleanup db',
testMatch: /global\.teardown\.ts/,
},
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
dependencies: ['setup db'],
},
]
});

然後我們在專案的 tests 目錄中建立一個 global.teardown.ts 檔案。這將用於在所有測試執行完畢後從資料庫刪除資料。

tests/global.teardown.ts
import { test as teardown } from '@playwright/test';

teardown('delete database', async ({ }) => {
console.log('deleting test database...');
// 刪除資料庫
});

測試篩選

所有測試篩選選項,例如 --grep/--grep-invert--shard、在命令列中直接按位置篩選,或使用 test.only(),都會直接選擇要執行的主要測試。如果這些測試屬於具有相依性的專案,來自這些相依性的所有測試也會執行。

您可以傳遞 --no-deps 命令列選項來忽略所有相依性和拆除。只有您直接選擇的專案會執行。

更多範例

更多詳細範例請查看:

選項 2:設定 globalSetup 和 globalTeardown

您可以在配置檔案中使用 globalSetup 選項來在執行所有測試之前設定某些內容。全域設定檔案必須匯出一個接受 config 物件的單一函式。此函式將在所有測試之前執行一次。

同樣地,使用 globalTeardown 在所有測試後執行一次某些操作。或者,讓 globalSetup 返回一個函式,該函式將用作全域拆除。您可以使用環境變數將資料(例如埠號、身份驗證令牌等)從全域設定傳遞到您的測試。

note

請注意,globalSetupglobalTeardown 缺少某些功能——請參閱簡介部分的詳細比較。考慮使用專案相依性來獲得完整的功能支援。

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

export default defineConfig({
globalSetup: require.resolve('./global-setup'),
globalTeardown: require.resolve('./global-teardown'),
});

範例

以下是一個全域設定範例,它進行一次身份驗證並在測試中重用身份驗證狀態。它使用配置檔案中的 baseURLstorageState 選項。

global-setup.ts
import { chromium, type FullConfig } from '@playwright/test';

async function globalSetup(config: FullConfig) {
const { baseURL, storageState } = config.projects[0].use;
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(baseURL!);
await page.getByLabel('User Name').fill('user');
await page.getByLabel('Password').fill('password');
await page.getByText('Sign in').click();
await page.context().storageState({ path: storageState as string });
await browser.close();
}

export default globalSetup;

在配置檔案中指定 globalSetupbaseURLstorageState

playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
globalSetup: require.resolve('./global-setup'),
use: {
baseURL: 'http://localhost:3000/',
storageState: 'state.json',
},
});

測試開始時已經通過身份驗證,因為我們指定了由全域設定填充的 storageState

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

test('test', async ({ page }) => {
await page.goto('/');
// 您已登入!
});

您可以透過 process.env 將其設定為環境變數,從全域設定檔案中讓任意資料在測試中可用。

global-setup.ts
import type { FullConfig } from '@playwright/test';

async function globalSetup(config: FullConfig) {
process.env.FOO = 'some data';
// Or a more complicated data structure as JSON:
process.env.BAR = JSON.stringify({ some: 'data' });
}

export default globalSetup;

測試可以存取在全域設定中設定的 process.env 屬性。

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

test('test', async ({ page }) => {
// 在 globalSetup 中設定的環境變數只在 test() 內可用。
const { FOO, BAR } = process.env;

// FOO 和 BAR 屬性已填充。
expect(FOO).toEqual('some data');

const complexData = JSON.parse(BAR);
expect(BAR).toEqual({ some: 'data' });
});

擷取全域設定期間失敗的追蹤

在某些情況下,擷取全域設定期間遇到的失敗追蹤可能很有用。為了做到這一點,您必須在設定中開始追蹤,並且必須確保如果發生錯誤,在拋出該錯誤之前停止追蹤。這可以透過將設定包裝在 try...catch 區塊中來實現。以下是擴展全域設定範例以擷取追蹤的範例。

global-setup.ts
import { chromium, type FullConfig } from '@playwright/test';

async function globalSetup(config: FullConfig) {
const { baseURL, storageState } = config.projects[0].use;
const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
try {
await context.tracing.start({ screenshots: true, snapshots: true });
await page.goto(baseURL!);
await page.getByLabel('User Name').fill('user');
await page.getByLabel('Password').fill('password');
await page.getByText('Sign in').click();
await context.storageState({ path: storageState as string });
await context.tracing.stop({
path: './test-results/setup-trace.zip',
});
await browser.close();
} catch (error) {
await context.tracing.stop({
path: './test-results/failed-setup-trace.zip',
});
await browser.close();
throw error;
}
}

export default globalSetup;