グローバルセットアップとティアダウン
はじめに
グローバルセットアップとティアダウンを設定する方法は2つあります。グローバルセットアップファイルを使用し、コンフィグのglobalSetupで設定する方法と、プロジェクト依存関係を使用する方法です。プロジェクト依存関係を使用すると、他のすべてのプロジェクトの前に実行されるプロジェクトを定義できます。これはPlaywrightテストランナーとより良く統合されるため、推奨されるアプローチです。HTMLレポートにはグローバルセットアップが含まれ、トレースが記録され、フィクスチャを使用できます。2つのアプローチの詳細な比較については、以下の表を参照してください。
| 機能 | プロジェクト依存関係 (推奨) | globalSetup (コンフィグオプション) |
|---|---|---|
| すべてのテストの前に実行 | ✅ はい | ✅ はい |
| HTMLレポートの可視性 | ✅ 個別のプロジェクトとして表示 | ❌ 表示されない |
| トレース記録 | ✅ 完全なトレースが利用可能 | ❌ サポートされていない |
| Playwrightフィクスチャ | ✅ 完全サポート | ❌ サポートされていない |
| ブラウザ管理 | ✅ browserフィクスチャ経由 | ❌ browserType.launch()経由で完全に手動 |
| 並列処理とリトライ | ✅ 標準コンフィグ経由でサポート | ❌ 適用外 |
headlessやtestIdAttributeのようなコンフィグオプション | ✅ 自動的に適用 | ❌ 無視される |
オプション1: プロジェクト依存関係
プロジェクト依存関係は、別のプロジェクトのテストが実行される前に実行する必要があるプロジェクトのリストです。これらは、グローバルセットアップアクションを設定するのに役立ち、あるプロジェクトが最初に実行されることに依存するようにできます。依存関係を使用すると、グローバルセットアップでトレースやその他の成果物を生成できます。
セットアップ
まず、「setup db」という名前の新しいプロジェクトを追加します。次に、global.setup.tsというファイルに一致するようにtestProject.testMatchプロパティを付与します。
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...');
// Initialize the database
});
import { test, expect } from '@playwright/test';
test('menu', async ({ page }) => {
// Your test that depends on the database
});
ティアダウン
セットアッププロジェクトに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...');
// Delete the 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オプションを使用して、すべてのテストを実行する前に一度何かをセットアップすることができます。グローバルセットアップファイルは、設定オブジェクトを受け取る単一の関数をエクスポートする必要があります。この関数は、すべてのテストの前に一度実行されます。
同様に、すべてのテストの後に一度何かを実行するにはglobalTeardownを使用します。または、globalSetupにグローバルティアダウンとして使用される関数を返させることもできます。ポート番号、認証トークンなどのデータを、環境変数を使用してグローバルセットアップからテストに渡すことができます。
globalSetupとglobalTeardownには一部の機能が欠けていることに注意してください。詳細な比較については、はじめにセクションを参照してください。完全な機能サポートを得るには、代わりにプロジェクト依存関係の使用を検討してください。
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: 'https://:3000/',
storageState: 'state.json',
},
});
グローバルセットアップによって入力されたstorageStateを指定するため、テストはすでに認証された状態で開始されます。
import { test } from '@playwright/test';
test('test', async ({ page }) => {
await page.goto('/');
// You are signed in!
});
グローバルセットアップファイルで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 }) => {
// 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ブロックでラップすることで実現できます。以下は、グローバルセットアップの例を拡張してトレースをキャプチャする例です。
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;