跳到主要内容

参数化测试

简介

您可以在测试级别或项目级别对测试进行参数化。

参数化测试

example.spec.ts
[
{ name: 'Alice', expected: 'Hello, Alice!' },
{ name: 'Bob', expected: 'Hello, Bob!' },
{ name: 'Charlie', expected: 'Hello, Charlie!' },
].forEach(({ name, expected }) => {
// 您也可以使用 test.describe() 或者多个测试来实现,只要测试名称唯一即可
test(`测试 ${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>({
// 定义一个选项并提供默认值
// 稍后我们可以在配置中覆盖它
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);
// ...
});

现在,我们可以通过使用项目来运行多个配置的测试。

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>({
// 定义一个选项并提供默认值
// 稍后我们可以在配置中覆盖它
person: ['John', { option: true }],

// 覆盖默认的 "page" 夹具
page: async ({ page, person }, use) => {
await page.goto('/chat');
// 我们使用 "person" 参数作为聊天室的"名称"
await page.getByLabel('User Name').fill(person);
await page.getByText('Enter chat room').click();
// 每个测试都会获得一个已经填写了用户名的 "page"
await use(page);
},
});
备注

参数化项目的行为在 1.18 版本中有所变化。了解更多

传递环境变量

您可以通过命令行使用环境变量来配置测试。

例如,考虑以下需要用户名和密码的测试文件。通常不建议将敏感信息存储在源代码中,因此我们需要一种从外部传递机密信息的方式。

example.spec.ts
test(`示例测试`, async ({ page }) => {
// ...
await page.getByLabel('用户名').fill(process.env.USER_NAME);
await page.getByLabel('密码').fill(process.env.PASSWORD);
});

您可以在命令行中设置机密用户名和密码来运行此测试。

USER_NAME=me PASSWORD=secret npx playwright test

同样地,配置文件也可以读取通过命令行传递的环境变量。

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

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

现在,您可以针对预发布环境或生产环境运行测试:

STAGING=1 npx playwright test

.env 文件

为了更便捷地管理环境变量,可以考虑使用 .env 文件。以下示例展示了如何使用 dotenv 包直接在配置文件中读取环境变量。

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

// 从 ".env" 文件读取配置
dotenv.config({ path: path.resolve(__dirname, '.env') });

// 或者从 "../my.env" 文件读取配置
dotenv.config({ path: path.resolve(__dirname, '..', 'my.env') });

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

现在,您只需编辑 .env 文件即可设置所需变量。

# .env 文件
STAGING=0
USER_NAME=me
PASSWORD=secret

像往常一样运行测试,环境变量将会自动加载。

npx playwright test

通过 CSV 文件创建测试

Playwright 测试运行器基于 Node.js 环境,这意味着您可以直接从文件系统读取文件,并使用您偏好的 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"

我们将使用 NPM 的 csv-parse 库基于此文件生成测试:

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);
});
}