テストのパラメータ化
はじめに
テストをテストレベルまたはプロジェクトレベルでパラメータ化できます。
パラメータ化されたテスト
[
{ 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);
});
});
前後のフック
ほとんどの場合、`beforeEach`、`beforeAll`、`afterEach`、`afterAll` のフックは `forEach` の外に配置して、フックが一度だけ実行されるようにする必要があります。
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()` 内に配置すると、各イテレーション/各個別のテストに対して実行されます。
[
{ 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は、複数のテストプロジェクトを同時に実行することをサポートしています。以下の例では、異なるオプションで2つのプロジェクトを実行します。
オプション `person` を宣言し、設定で値を設定します。最初のプロジェクトは `Alice` の値で実行され、2番目のプロジェクトは `Bob` の値で実行されます。
- TypeScript
- JavaScript
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 }],
});
const base = require('@playwright/test');
exports.test = base.test.extend({
// Define an option and provide a default value.
// We can later override it in the config.
person: ['John', { option: true }],
});
このオプションは、フィクスチャと同様にテストで使用できます。
import { test } from './my-test';
test('test 1', async ({ page, person }) => {
await page.goto(`/index.html`);
await expect(page.locator('#node')).toContainText(person);
// ...
});
これで、プロジェクトを使用して複数の構成でテストを実行できます。
- TypeScript
- JavaScript
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' },
},
]
});
// @ts-check
module.exports = defineConfig({
projects: [
{
name: 'alice',
use: { person: 'Alice' },
},
{
name: 'bob',
use: { person: 'Bob' },
},
]
});
フィクスチャでこのオプションを使用することもできます。フィクスチャの詳細については、こちらをご覧ください。
- TypeScript
- JavaScript
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);
},
});
const base = require('@playwright/test');
exports.test = base.test.extend({
// 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);
},
});
パラメータ化されたプロジェクトの動作はバージョン1.18で変更されました。詳細はこちら。
環境変数の受け渡し
コマンドラインから環境変数を使用してテストを設定できます。
たとえば、ユーザー名とパスワードを必要とする次のテストファイルを考えてみましょう。通常、機密情報をソースコードに保存しないことが良い習慣であるため、外部から機密情報を渡す方法が必要になります。
test(`example test`, async ({ page }) => {
// ...
await page.getByLabel('User Name').fill(process.env.USER_NAME);
await page.getByLabel('Password').fill(process.env.PASSWORD);
});
このテストは、コマンドラインで機密のユーザー名とパスワードを設定して実行できます。
- Bash
- PowerShell
- Batch
USER_NAME=me PASSWORD=secret npx playwright test
$env:USER_NAME=me
$env:PASSWORD=secret
npx playwright test
set USER_NAME=me
set PASSWORD=secret
npx playwright test
同様に、設定ファイルもコマンドラインから渡された環境変数を読み取ることができます。
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
baseURL: process.env.STAGING === '1' ? 'http://staging.example.test/' : 'http://example.test/',
}
});
これで、ステージング環境または本番環境に対してテストを実行できます。
- Bash
- PowerShell
- Batch
STAGING=1 npx playwright test
$env:STAGING=1
npx playwright test
set STAGING=1
npx playwright test
.env ファイル
環境変数を管理しやすくするために、`.env` ファイルのようなものを検討してください。以下は、`dotenv` パッケージを使用して設定ファイル内で環境変数を直接読み取る例です。
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/',
}
});
これで、`.env` ファイルを編集するだけで、任意の変数を設定できます。
# .env file
STAGING=0
USER_NAME=me
PASSWORD=secret
通常通りテストを実行してください。環境変数が認識されるはずです。
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"
これに基づいて、NPMのcsv-parseライブラリを使用してテストを生成します。
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);
});
}