用語集 · UI 自動化
テストの独立性(Test Isolation)
英語: Test isolation
別名: テストの分離, テスト分離, isolated tests, テストの独立性とは
定義
各テストが自分で状態を準備し、ほかのテストに依存も影響もせず、どの順序でも並列でも単独で合格できるという性質です。
独立したテストは、必要なものをすべて自分で作り、ほかのテストが残したものに頼らず、ほかのテストの結果を変えるようなものを残しません。どのテストでも単独で実行でき、スイート全体を逆順で実行しても、8 つの並列ワーカーで実行しても同じ結果になるなら、そのスイートは独立しています。並列実行やシャーディングを安全にしているのは、この独立性です。
例
独立していない例:2 つ目のテストが 1 つ目に依存しています。
test('creates a project', async ({ page }) => {
await page.goto('/projects/new');
await page.getByLabel('Name').fill('Apollo');
await page.getByRole('button', { name: 'Create' }).click();
});
test('renames the project', async ({ page }) => {
await page.goto('/projects/apollo'); // fails if run alone or first
});
独立した例:各テストが一意の名前を付けたデータを API 経由で自分で作成します。
test('renames a project', async ({ page, request }) => {
const name = `proj-${crypto.randomUUID()}`;
const res = await request.post('/api/projects', { data: { name } });
const { id } = await res.json();
await page.goto(`/projects/${id}`);
// ...rename and assert
});
Playwright はブラウザーのレベルで独立性を助けてくれます。各テストには新しい BrowserContext が割り当てられるため、Cookie、ローカルストレージ、セッションがテスト間で漏れることはありません。
状態が漏れる原因
- 共有アカウントや共有レコードをテストが変更すること。たとえば、すべてのテストが設定を書き換える 1 人の「テストユーザー」です。
- テストコード内の静的・グローバルな状態。シングルトンのドライバーやクラスレベルの変数などです。
- 後片付けされないデータベースの行、あるいはほかのテストも書き込むテーブルの件数に対してアサーションするテスト。
- フィーチャーフラグ、メールの受信箱、時刻、キャッシュなどの外部の状態。
確認方法
テストをランダムな順序で実行します。JUnit 5 は @TestMethodOrder(MethodOrderer.Random.class) をサポートしており、junit-platform.properties ですべてのクラスのデフォルト順序をランダムに設定することもできます。個々のテストを単独で実行します。普段より多いワーカー数でスイートを実行します。結果が変わるテストは独立していません。
完全な独立性にはコストがかかり、特にセットアップが遅い場合は顕著です。よくある妥協策は、コストが高く読み取り専用のデータはワーカー単位で共有し、テストが書き込むものはすべてそのテスト固有にしておくことです。