Skip to main content

參數化測試

簡介

您可以在測試層級或專案層級上參數化測試。

參數化測試

example.spec.ts
[
{ name: 'Alice', expected: 'Hello, Alice!' },
{ name: 'Bob', expected: 'Hello, Bob!' },
{ name: 'Charlie', expected: 'Hello, Charlie!' },
].forEach(({ name, expected }) => {
// You can also do it with test.describe() or with multiple tests as long the test name is unique.
test(`testing with ${name}`, async ({ page }) => {
await page.goto(`https://example.com/greet?name=${name}`);
await expect(page.getByRole('heading')).toHaveText(expected);
});
});

前後掛勾

大部分時候您應該將 beforeEachbeforeAllafterEachafterAll 掛勾放在 forEach 外面,這樣掛勾只會執行一次:

example.spec.ts
test.beforeEach(async ({ page }) => {
// ...
});

test.afterEach(async ({ page }) => {
// ...
});

[
{ name: 'Alice', expected: 'Hello, Alice!' },
{ name: 'Bob', expected: 'Hello, Bob!' },
{ name: 'Charlie', expected: 'Hello, Charlie!' },
].forEach(({ name, expected }) => {
test(`testing with ${name}`, async ({ page }) => {
await page.goto(`https://example.com/greet?name=${name}`);
await expect(page.getByRole('heading')).toHaveText(expected);
});
});

如果您想為每個測試設定掛勾,您可以將它們放在 describe() 內 - 這樣它們將為每次迭代/每個個別測試執行:

example.spec.ts
[
{ name: 'Alice', expected: 'Hello, Alice!' },
{ name: 'Bob', expected: 'Hello, Bob!' },
{ name: 'Charlie', expected: 'Hello, Charlie!' },
].forEach(({ name, expected }) => {
test.describe(() => {
test.beforeEach(async ({ page }) => {
await page.goto(`https://example.com/greet?name=${name}`);
});
test(`testing with ${expected}`, async ({ page }) => {
await expect(page.getByRole('heading')).toHaveText(expected);
});
});
});

參數化專案

Playwright Test 支援同時執行多個測試專案。在以下範例中,我們將使用不同選項執行兩個專案。

我們宣告選項 person 並在組態設定中設定值。第一個專案使用值 Alice 執行,第二個使用值 Bob 執行。

my-test.ts
import { test as base } from '@playwright/test';

export type TestOptions = {
person: string;
};

export const test = base.extend<TestOptions>({
// Define an option and provide a default value.
// We can later override it in the config.
person: ['John', { option: true }],
});

我們可以在測試中使用此選項,類似於佈置

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

test('test 1', async ({ page, person }) => {
await page.goto(`/index.html`);
await expect(page.locator('#node')).toContainText(person);
// ...
});

Now, we can run tests in multiple configurations by using projects.

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

export default defineConfig<TestOptions>({
projects: [
{
name: 'alice',
use: { person: 'Alice' },
},
{
name: 'bob',
use: { person: 'Bob' },
},
]
});

我們也可以在佈置中使用選項。了解更多關於佈置

my-test.ts
import { test as base } from '@playwright/test';

export type TestOptions = {
person: string;
};

export const test = base.extend<TestOptions>({
// Define an option and provide a default value.
// We can later override it in the config.
person: ['John', { option: true }],

// Override default "page" fixture.
page: async ({ page, person }, use) => {
await page.goto('/chat');
// We use "person" parameter as a "name" for the chat room.
await page.getByLabel('User Name').fill(person);
await page.getByText('Enter chat room').click();
// Each test will get a "page" that already has the person name.
await use(page);
},
});
note

Parameterized projects behavior has changed in version 1.18. Learn more.

傳遞環境變數

您可以使用環境變數從命令列組態設定測試。

例如,考慮以下需要使用者名稱和密碼的測試檔案。通常最好不要將您的機密資料儲存在原始碼中,所以我們需要一種從外部傳遞機密資料的方法。

example.spec.ts
test(`example test`, async ({ page }) => {
// ...
await page.getByLabel('User Name').fill(process.env.USER_NAME);
await page.getByLabel('Password').fill(process.env.PASSWORD);
});

您可以在命令列中設定您的機密使用者名稱和密碼來執行此測試。

USER_NAME=me PASSWORD=secret npx playwright test

Similarly, configuration file can also read environment variables passed through the command line.

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

export default defineConfig({
use: {
baseURL: process.env.STAGING === '1' ? 'http://staging.example.test/' : 'http://example.test/',
}
});

Now, you can run tests against a staging or a production environment:

STAGING=1 npx playwright test

.env files

為了讓環境變數更容易管理,請考慮使用類似 .env 檔案的東西。以下是一個使用 dotenv 套件在組態設定檔案中直接讀取環境變數的範例。

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

// Read from ".env" file.
dotenv.config({ path: path.resolve(__dirname, '.env') });

// Alternatively, read from "../my.env" file.
dotenv.config({ path: path.resolve(__dirname, '..', 'my.env') });

export default defineConfig({
use: {
baseURL: process.env.STAGING === '1' ? 'http://staging.example.test/' : 'http://example.test/',
}
});

Now, you can just edit .env file to set any variables you'd like.

# .env file
STAGING=0
USER_NAME=me
PASSWORD=secret

Run tests as usual, your environment variables should be picked up.

npx playwright test

透過 CSV 檔案建立測試

Playwright 測試執行器在 Node.js 中執行,這意味著您可以直接從檔案系統讀取檔案,並使用您偏好的 CSV 程式庫解析它們。

例如,請見此 CSV 檔案,在我們的範例 input.csv 中:

"test_case","some_value","some_other_value"
"value 1","value 11","foobar1"
"value 2","value 22","foobar21"
"value 3","value 33","foobar321"
"value 4","value 44","foobar4321"

Based on this we'll generate some tests by using the csv-parse library from NPM:

test.spec.ts
import fs from 'fs';
import path from 'path';
import { test } from '@playwright/test';
import { parse } from 'csv-parse/sync';

const records = parse(fs.readFileSync(path.join(__dirname, 'input.csv')), {
columns: true,
skip_empty_lines: true
});

for (const record of records) {
test(`foo: ${record.test_case}`, async ({ page }) => {
console.log(record.test_case, record.some_value, record.some_other_value);
});
}