分離
はじめに
Playwrightで書かれたテストは、ブラウザコンテキストと呼ばれる分離されたクリーンな環境で実行されます。この分離モデルにより、再現性が向上し、テストの連鎖的な失敗を防ぎます。
テスト分離とは?
テスト分離とは、各テストが他のテストから完全に分離されている状態を指します。すべてのテストは他のテストから独立して実行されます。これは、各テストが独自のローカルストレージ、セッションストレージ、クッキーなどを持つことを意味します。Playwrightは、シークレットモードのようなプロファイルに相当するBrowserContextを使用することでこれを実現します。これらは作成が高速で費用がかからず、単一のブラウザで実行されている場合でも完全に分離されます。Playwrightは各テスト用にコンテキストを作成し、そのコンテキスト内でデフォルトのPageを提供します。
テスト分離が重要な理由
- 失敗の持ち越しがない。1つのテストが失敗しても、他のテストには影響しません。
- エラーや不安定さのデバッグが簡単。1つのテストを何度でも実行できるため。
- 並行実行やシャーディングなどを行う際に、順序を考慮する必要がない。
テスト分離の2つの方法
テスト分離には、ゼロから開始するか、途中でクリーンアップするかの2つの異なる戦略があります。テストの途中でクリーンアップすることの問題点は、クリーンアップを忘れやすいことや、「訪問済みリンク」のようにクリーンアップが不可能なものがあることです。あるテストの状態が次のテストに漏れてしまうと、テストが失敗したり、問題が別のテストから来ているためデバッグが困難になったりする可能性があります。ゼロから開始するということは、すべてが新しいということなので、テストが失敗した場合、デバッグはそのテスト内だけを見れば済みます。
Playwrightがテスト分離を実現する方法
Playwrightはテスト分離を実現するためにブラウザコンテキストを使用します。各テストは独自のブラウザコンテキストを持ちます。テストを実行するたびに新しいブラウザコンテキストが作成されます。Playwrightをテストランナーとして使用する場合、ブラウザコンテキストはデフォルトで作成されます。それ以外の場合は、ブラウザコンテキストを手動で作成できます。
- 同期
- 非同期
browser = playwright.chromium.launch()
context = browser.new_context()
page = context.new_page()
browser = await playwright.chromium.launch()
context = await browser.new_context()
page = await context.new_page()
ブラウザコンテキストは、モバイルデバイス、パーミッション、ロケール、配色を含むマルチページシナリオをエミュレートするためにも使用できます。詳細については、エミュレーションガイドをご覧ください。
単一テストでの複数コンテキスト
Playwrightは、単一のシナリオ内で複数のブラウザコンテキストを作成できます。これは、チャットのようなマルチユーザー機能をテストする場合に役立ちます。
- 同期
- 非同期
from playwright.sync_api import sync_playwright, Playwright
def run(playwright: Playwright):
# create a chromium browser instance
chromium = playwright.chromium
browser = chromium.launch()
# create two isolated browser contexts
user_context = browser.new_context()
admin_context = browser.new_context()
# create pages and interact with contexts independently
with sync_playwright() as playwright:
run(playwright)
import asyncio
from playwright.async_api import async_playwright, Playwright
async def run(playwright: Playwright):
# create a chromium browser instance
chromium = playwright.chromium
browser = await chromium.launch()
# create two isolated browser contexts
user_context = await browser.new_context()
admin_context = await browser.new_context()
# create pages and interact with contexts independently
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())