💯

Playwrightで複数ユーザーを使ったテストが素敵に書ける

2025/01/20に公開

【複数ユーザーのE2Eテストを楽に!】Playwrightで同時ログインを扱う方法

https://www.youtube.com/watch?v=AP2YD6rllyM

「管理者でログインしたあとに、一般ユーザーに切り替えて同じテストを続行したい!」
そんなときに便利なのがPlaywrightで 複数BrowserContext を使ったテストです。この記事では、上の動画でシェアしている内容をかいつまんで紹介します。

結論から

  • 複数のBrowserContext を使うことで、同じテスト内で複数のユーザーをシミュレート可能
  • Playwrightのセッション保持の仕組みのおかげで「管理者→一般ユーザー」など、切り替えを行う際に ログアウト・ログイン をいちいち書かなくてもOK
  • 番外編として forループ を使ってテストをスッキリ書くこともできる

もっと詳しく知りたい場合や、実際の動きを映像で確認したい場合には、上の動画をご覧いただくのがおすすめです。

なぜ複数BrowserContextが便利なのか?

動画はこちら

そもそも「BrowserContextとは?」、というところですが、PlaywrightのBrowserContextは、ブラウザ内で独立したセッションを作成する機能です。これは、同じブラウザ内で複数のユーザーが別々のウィンドウを使って作業するようなものです。

各コンテキストは、クッキーやキャッシュ、ストレージなどのデータを他と共有しないため、テストの独立性と信頼性を高めます。

たとえばECサイトのテストで、次のようなシナリオを考えてみてください。

  1. 管理者ユーザー としてログインし、商品の登録を行う
  2. 一般ユーザー としてログインし直し、登録された商品を購入できるか確認する

通常なら「一度ログアウトしてから、別ユーザーでログイン」とコードを書きがちですが、Playwrightの BrowserContext を使えば、

  • それぞれのコンテキストに 異なるログイン情報 をあらかじめ紐づけ
  • 1つのテストで2種類以上のユーザー操作を連携して書ける

こうすることで、テストコードが冗長にならず、管理者→一般ユーザー の流れをスムーズに実現できます。

以下が実際のテストのイメージです( 公式サイト から抜粋)

import { test } from '@playwright/test';

test('admin and user', async ({ browser }) => {
  // 管理者ユーザーでBrowserContextを作る
  const adminContext = await browser.newContext({ storageState: 'playwright/.auth/admin.json' });
  // 管理者ユーザーのセッション情報を使ったPageを生成する
  const adminPage = await adminContext.newPage();

  // 一般ユーザーでBrowserContextを作る
  const userContext = await browser.newContext({ storageState: 'playwright/.auth/user.json' });
  // 一般ユーザーのセッション情報を使ったPageを生成する
  const userPage = await userContext.newPage();

  // あとは `adminPage` や`userPage` を活用して管理者ユーザーと一般ユーザーを使ったテストを書く
  // TODO: ここにテストを書く

  // 最後にお片付け
  await adminContext.close();
  await userContext.close();
});

上のコードは、以下を知っている前提としています 🙏 storageState 周りが意味不明な方はぜひ動画を参考にしてみてください!

また、冒頭の動画 ではECサイトではなく、Xもどきのサイトで複数ユーザーを使って実際にテストコードを書いているので、気になる人は見てみてください

さらに応用:ループして同テストを別ユーザーで確認

動画はこちら

上の手法はユーザーを切り替えるときにも使えますが、他にも応用できます。

たとえばXのようなサービスなら「通常ユーザーでもプレミアムユーザーでも投稿が行える」といったケースで、ユーザーごとに同じテストを実行したいことがあります。これをコピペで別々に書くのは冗長ですし保守性がとても悪いです。

そこで、Playwrightで複数のBrowserContextを使えば、これをまとめてテストできます。イメージとしては、単純に for でループを回すだけです!

import { test } from '@playwright/test';

test('admin and user', async ({ browser }) => {
  // 管理者ユーザー
  const adminContext = await browser.newContext({ storageState: 'playwright/.auth/admin.json' });
  const adminPage = await adminContext.newPage();

  // 一般ユーザー
  const userContext = await browser.newContext({ storageState: 'playwright/.auth/user.json' });
  const userPage = await userContext.newPage();

  // あとは `adminPage` や`userPage` をループで、同一のテストを実行する
  for (const page of [adminPage, userPage]) {
    // TODO: ★ここに共通のテストを書く★
  }

  // 最後にお片付け
  await adminContext.close();
  await userContext.close();
});

ただし、これには「テスト時間が長くなる可能性がある」というちょっとした課題があります。2,3種類のユーザーでシンプルなテストなら良いですが、10種類のユーザーなどでテストがそれなりに長いと、一つの test としてはかなり実行時間が長くなってしまいがちです。よって、 test 自体を for ループで回すように、以下のように書くこともできます。

const users = [
  { name: 'Premium', storageState: 'premium.json' },
  { name: 'Normal',  storageState: 'normal.json' }
];

for (const user of users) {
  test(`Should post as ${user.name}`, async ({ browser }) => {
    const context = await browser.newContext({ storageState: user.storageState });
    const page = await context.newPage();
    // ...ここで同じ動作をテスト
  });
}

上記のようにすることで、テスト毎のパフォーマンスの違いも特に無く、スケールするデータドリブンなテストっぽいアプローチがとれます。(この方法はこの方法で fixture との相性があまり良くないので、ケースバイケースで使い方を検討する必要があります)

まとめ:複数ユーザーが動くシナリオをスムーズにテストしよう

  • 複数のBrowserContextを利用すれば、 1つのテスト内で複数ロール(ユーザー) を扱える
  • ログイン情報を別々に読み込むことで、切り替え操作を省いてスッキリしたコードに
  • ループを活用することで、同様のテストを複数ユーザーで簡単に実施可能

ECサイトやチャットアプリ、承認フローのある業務システムなど、「ユーザー同士のインタラクトをテストしたい」ときにはぜひ試してみてください!

本記事がテストコードの作成・保守のお役に立てば幸いです。複数ユーザーを使ったE2Eテストをさくっと書きたいときは、ぜひPlaywrightの複数BrowserContextを試してみてください!


他にもPlaywright入門動画もチェック

Playwright入門な方へ

https://www.youtube.com/watch?v=kLOss2qjm_I

VSCodeでPlaywrightのテストを書く方に役立つ情報かも

https://www.youtube.com/watch?v=PumAhEpKoC0

Playwrightでログイン状態を保持する仕組みについて

https://www.youtube.com/watch?v=6ZtwTjcIw5w

Playwrightで複数セッションを管理する方法について

https://www.youtube.com/watch?v=l-7h2lK85Lw

Discussion