Skip to main content

全域設定和拆卸

簡介

有兩種方式可以配置全域設定和拆卸: 使用全域設定檔案並在配置中設定globalSetup或使用專案相依性。使用專案相依性時,你可以定義一個在所有其他專案之前執行的專案。這是配置全域設定的推薦方式,因為使用專案相依性時,你的 HTML 報告將顯示全域設定,追蹤檢視器將記錄設定的追蹤,並且可以使用 fixtures。

選項 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' 專案。我們接著建立一個 setup 測試,儲存在專案的根目錄(注意,setup 和 teardown 程式碼必須透過呼叫 test() 函式來定義為常規測試):

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

setup('create new database', async ({ }) => {
console.log('creating new database...');
// Initialize the database
});
tests/menu.spec.ts
import { test, expect } from '@playwright/test';

test('menu', async ({ page }) => {
// Your test that depends on the database
});

拆解

你可以通過在你的設定專案中添加 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'],
},
]
});

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

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

teardown('delete database', async ({ }) => {
console.log('deleting test database...');
// Delete the database
});

更多範例

如需更詳細的範例,請查看:

選項 2: 設定 globalSetup 和 globalTeardown

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

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

note

使用 globalSetupglobalTeardown 不會產生追蹤或檔案,並且在設定檔中指定的選項如 headlesstestIdAttribute 不會被應用。如果你想產生追蹤和檔案並遵守設定選項,請使用 project dependencies

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('/');
// You are signed in!
});

您可以通過 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 }) => {
// environment variables which are set in globalSetup are only available inside test().
const { FOO, BAR } = process.env;

// FOO and BAR properties are populated.
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;