全域設定和拆除
簡介
有兩種方式可以配置全域設定和拆除:使用全域設定檔案並在配置中設定 globalSetup
或使用專案相依性。使用專案相依性時,您可以定義一個在所有其他專案之前執行的專案。這是推薦的方式,因為它與 Playwright 測試執行器整合得更好:您的 HTML 報告將包含全域設定,追蹤將被記錄,並且可以使用佈置。以下表格提供兩種方式的詳細比較。
功能 | 專案相依性(推薦) | globalSetup (配置選項) |
---|---|---|
在所有測試前執行 | ✅ 是 | ✅ 是 |
HTML 報告可見性 | ✅ 顯示為獨立專案 | ❌ 不顯示 |
追蹤記錄 | ✅ 完整追蹤可用 | ❌ 不支援 |
Playwright 佈置 | ✅ 完全支援 | ❌ 不支援 |
瀏覽器管理 | ✅ 透過 browser 佈置 | ❌ 透過 browserType.launch() 完全手動 |
平行性和重試 | ✅ 透過標準配置支援 | ❌ 不適用 |
headless 或 testIdAttribute 等配置選項 | ✅ 自動套用 | ❌ 忽略 |
選項 1:專案相依性
專案相依性是需要在另一個專案的測試執行之前執行的專案列表。它們對於配置全域設定動作非常有用,以便一個專案依賴於此項目先執行。使用相依性允許全域設定產生追蹤和其他成品。
設定
首先我們新增一個名稱為 'setup db' 的新專案。然後我們給它一個 testProject.testMatch 屬性,以匹配名為 global.setup.ts
的檔案:
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
// ...
projects: [
{
name: 'setup db',
testMatch: /global\.setup\.ts/,
},
// {
// other project
// }
]
});
然後我們將 testProject.dependencies 屬性新增到依賴設定專案的專案中,並將我們在上一步中定義的相依性專案名稱傳入陣列中:
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() 函式定義為常規測試):
import { test as setup } from '@playwright/test';
setup('create new database', async ({ }) => {
console.log('creating new database...');
// 初始化資料庫
});
import { test, expect } from '@playwright/test';
test('menu', async ({ page }) => {
// 您依賴資料庫的測試
});
拆除
您可以透過在設定專案中新增 testProject.teardown 屬性來拆除您的設定。這將在所有相依專案執行完畢後執行。
首先,我們將 testProject.teardown 屬性新增到設定專案中,名稱為 'cleanup db',這是我們在上一步中給拆除專案的名稱:
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
檔案。這將用於在所有測試執行完畢後從資料庫刪除資料。
import { test as teardown } from '@playwright/test';
teardown('delete database', async ({ }) => {
console.log('deleting test database...');
// 刪除資料庫
});
測試篩選
所有測試篩選選項,例如 --grep
/--grep-invert
、--shard
、在命令列中直接按位置篩選,或使用 test.only()
,都會直接選擇要執行的主要測試。如果這些測試屬於具有相依性的專案,來自這些相依性的所有測試也會執行。
您可以傳遞 --no-deps
命令列選項來忽略所有相依性和拆除。只有您直接選擇的專案會執行。
更多範例
更多詳細範例請查看:
- 我們的身份驗證指南
- 我們的部落格文章 A better global setup in Playwright reusing login with project dependencies
- v1.31 發布影片 觀看示範
選項 2:設定 globalSetup 和 globalTeardown
您可以在配置檔案中使用 globalSetup
選項來在執行所有測試之前設定某些內容。全域設定檔案必須匯出一個接受 config 物件的單一函式。此函式將在所有測試之前執行一次。
同樣地,使用 globalTeardown
在所有測試後執行一次某些操作。或者,讓 globalSetup
返回一個函式,該函式將用作全域拆除。您可以使用環境變數將資料(例如埠號、身份驗證令牌等)從全域設定傳遞到您的測試。
import { defineConfig } from '@playwright/test';
export default defineConfig({
globalSetup: require.resolve('./global-setup'),
globalTeardown: require.resolve('./global-teardown'),
});
範例
以下是一個全域設定範例,它進行一次身份驗證並在測試中重用身份驗證狀態。它使用配置檔案中的 baseURL
和 storageState
選項。
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;
在配置檔案中指定 globalSetup
、baseURL
和 storageState
。
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
將其設定為環境變數,從全域設定檔案中讓任意資料在測試中可用。
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
區塊中來實現。以下是擴展全域設定範例以擷取追蹤的範例。
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;