ユースケーステストとは?基本・代替・例外フローの設計方法+Playwright実装

テスト自動化

ユースケーステストとは、ユーザーが目的を達成するまでの一連の操作フロー(ユースケース)をテストシナリオに変換するテスト設計技法です。E2Eテストのシナリオ設計・リグレッションテストの優先度付けに特に効果を発揮します。

💡 一言でいうと
ユースケーステスト = 「ユーザーが目的を達成するまでの操作を丸ごとテストする手法

ユースケーステストを使うと「ユーザーが実際に行う操作」をそのままテストシナリオに変換でき、「動作はするが使えない」というユーザー目線のバグを根こそぎ発見できます。

📌 この記事はこんな方におすすめ

  • ユースケーステストを初めて学ぶQAエンジニア・開発者
  • E2Eテストのシナリオをどう設計すればいいか悩んでいる方
  • ユーザー目線のテストケースを体系的に作りたい方
  • Playwright × pytestでのE2Eテスト設計に役立てたい方

✅ この記事を読むと得られること

  • ユースケーステストの概念と基本フロー・代替フローの設計方法がわかる
  • 購入フロー・会員登録など実務でよく使う場面への適用方法がわかる
  • Playwright × pytestでのE2Eテストへの変換方法がわかる

👤 この記事を書いた人

QAエンジニア・テスト自動化エンジニアとして15年以上の実務経験を持つ Yoshi が執筆。ユースケーステストはE2Eテストのシナリオ設計で毎日活用している技法です。実装コードはGitHubで公開中:github.com/YOSHITSUGU728/automated-testing-portfolio

「単体テストは全部通っているのに、実際に使ってみたら動かない」「正常系しかテストしていなくて、ユーザーが取りそうな操作のバグが本番で発生した」——こうした問題はユーザー目線のテスト設計が不足していることが原因です。

  • 単体テストや機能テストだけでは「ユーザーの操作フロー全体」が検証できない
  • 正常系(基本フロー)しかテストしておらず、代替フロー・例外フローが見落とされる
  • テストシナリオがエンジニアの視点で作られており、実際のユーザー操作と乖離している

ユースケーステストはこうした問題を解決する技法です。この記事では概念から具体的なシナリオ設計・Playwright E2Eテストへの応用まで一気通貫で解説します。

📌 結論

  • 「ユーザーのゴールへの一連の操作」を基本フロー・代替フロー・例外フローに分けて設計するテスト設計技法
  • 基本フローで正常系を・代替フローで分岐を・例外フローでエラー処理を検証する
  • Playwright × pytestでは1ユースケース=1テストファイルの構成がベストプラクティス

ユースケーステストとは?

ユースケーステストとは、「ユーザーがシステムを使って目的を達成するまでの一連の操作フロー(ユースケース)」をテストシナリオに変換するテスト設計技法です。

例えば「商品を購入する」というユースケースなら、ログイン→商品選択→カート追加→決済情報入力→注文確定→完了確認という一連のフローをそのままテストシナリオにします。ユーザーの視点からシステムを検証するため、単体テストでは発見できない「フロー全体で初めて現れるバグ」を見つけられます。

比較項目単体テスト・機能テストユースケーステスト
視点開発者・機能単位ユーザー・ゴール単位
テスト範囲個別の機能・入出力操作フロー全体・画面遷移
発見できるバグロジックのバグフロー・統合・UXのバグ
自動化ツールpytest・unittestPlaywright・Selenium

状態遷移テストとの違いとは?

同じ「フローをテストする」技法でも、ユースケーステストと状態遷移テストでは視点と目的が異なります。実務では混同されやすいため整理しておきます。

比較項目ユースケーステスト状態遷移テスト
視点ユーザーの目的達成フローシステムの状態と遷移の正しさ
検証内容基本フロー・代替フロー・例外フロー正常遷移・無効遷移
向いているシステムUI操作が主体のシステム全般状態を持つシステム(EC・予約)
よく使う場面購入フロー・会員登録・検索注文ステータス・ログイン状態管理

💡 判断基準

  • 「ユーザーが何ステップで目的を達成するか」を確認したい → ユースケーステスト
  • 「この状態からこの操作は有効か・無効か」を確認したい → 状態遷移テスト
  • 実務では両方を組み合わせるのが標準。ユースケーステストで正常フローを、状態遷移テストで無効遷移を補完する。

ユースケーステストとE2Eテストの違いとは?

よく混同される2つの概念ですが、役割がまったく異なります

項目ユースケーステストE2Eテスト
種類テスト設計の技法テスト実行の方式
役割「何をテストするか」を設計する「どうテストを実行するか」の手段
ツール設計書・スプレッドシートPlaywright・Selenium・Cypress
💡 関係性:ユースケーステストで設計したシナリオを、PlaywrightなどのツールでE2Eテストとして実装するという流れが実務での標準です。設計なしにいきなりE2Eテストを書くと、何を確認しているのか曖昧なテストコードができあがります。

ユースケーステストの基本構造とは?

ユースケーステストは「基本フロー」「代替フロー」「例外フロー」の3つで構成されます。

フロー種別内容例(商品購入)
基本フロー
(Basic Flow)
最もよくある正常系の操作手順ログイン→商品選択→カート追加→決済→完了
代替フロー
(Alternative Flow)
正常だが別の経路をたどる操作ゲスト購入(ログインなし)・クーポン適用・在庫なしで別商品選択
例外フロー
(Exception Flow)
エラーや異常が発生する操作決済失敗・セッション期限切れ・必須項目未入力
💡 ポイント:多くのQAチームが「基本フロー(正常系)」しかテストしていません。ユースケーステストの真価は代替フロー・例外フローの洗い出しにあります。「ゲスト購入ってテストした?」「決済失敗したときのリトライ動作は?」という問いかけから代替・例外フローを発掘しましょう。

📊 ユースケース「商品を購入する」のフロー図

基本
👤 開始
ログイン
商品選択
カート追加
決済
🎯 完了

代替
クーポン適用
🎯 完了
← 別経路・正常

例外
決済失敗
🔄 エラー処理
← エラー・異常

基本フロー(正常系) 
代替フロー(別経路・正常) 
例外フロー(エラー・異常)

実例①:商品購入ユースケースのテスト設計

ECサイトの「商品を購入する」ユースケースを基本フロー・代替フロー・例外フローに分けてテストシナリオを設計します。

基本フロー(正常系)

ステップユーザーの操作システムの応答(確認ポイント)
Step 1ログインするダッシュボードが表示される
Step 2商品を検索・選択する商品詳細ページが表示される
Step 3カートに追加するカートのバッジ数が増える
Step 4カートから購入手続きに進む注文確認ページが表示される
Step 5支払い情報を入力・注文確定する注文完了ページが表示され確認メールが送信される

代替フロー(正常だが別経路)

代替フロー発生条件確認ポイント
ゲスト購入ログインせずに購入するゲスト購入フローが正しく完了するか
クーポン適用クーポンコードを入力して割引する割引後の金額が正しく計算されるか
複数商品購入複数の商品をカートに入れて購入する合計金額・送料が正しく計算されるか

例外フロー(エラー・異常)

例外フロー発生条件確認ポイント
決済失敗クレジットカードが決済拒否されたエラーメッセージが表示されカートの中身が保持されるか
在庫切れ決済中に在庫がなくなった適切なエラーが表示され二重課金が発生しないか
セッション切れ決済画面でセッションが期限切れになったログインページへリダイレクトされカートが保持されるか

実例②:会員登録ユースケースのテスト設計

もう一つの代表的なユースケース「会員登録する」のテスト設計です。

フロー種別シナリオ確認ポイント
基本フローメールアドレス・パスワードを入力して登録完了確認メール受信・ログイン可能になるか
代替フロー①SNS連携(Google / Apple)で登録OAuth認証が正しく完了しアカウントが作成されるか
代替フロー②招待リンクから登録招待特典が正しく付与されるか
例外フロー①すでに登録済みのメールアドレスで登録重複登録エラーが表示されるか
例外フロー②メール確認リンクが期限切れ再送信ボタンが表示されるか

Playwright × pytestへの応用

ユースケーステストで設計したシナリオはPlaywright × pytestのE2Eテストに直接変換できます。1ユースケース=1テストファイルの構成が実務のベストプラクティスです。

フォルダ構成の例

tests/
├── conftest.py
└── e2e/
    ├── test_purchase.py        # ユースケース:商品を購入する
    ├── test_register.py        # ユースケース:会員登録する
    └── test_login.py           # ユースケース:ログインする

test_purchase.py:商品購入ユースケースのE2Eテスト

import pytest
from playwright.sync_api import Page, expect

# ── 基本フロー ──────────────────────────────────
def test_purchase_basic_flow(logged_in_page: Page):
    """基本フロー:ログイン済みユーザーが商品を購入する"""
    # Step 2: 商品を選択
    logged_in_page.goto("localhost:3000/products/1")
    expect(logged_in_page.locator("h1.product-title")).to_be_visible()

    # Step 3: カートに追加
    logged_in_page.click("#add-to-cart")
    expect(logged_in_page.locator(".cart-badge")).to_have_text("1")

    # Step 4: 購入手続きへ
    logged_in_page.goto("localhost:3000/cart")
    logged_in_page.click("#checkout-btn")

    # Step 5: 注文確定
    logged_in_page.fill("#card-number", "4111111111111111")
    logged_in_page.fill("#expiry", "12/26")
    logged_in_page.fill("#cvv", "123")
    logged_in_page.click("#confirm-order-btn")
    expect(logged_in_page.locator(".order-complete")).to_be_visible()

# ── 代替フロー ──────────────────────────────────
def test_purchase_with_coupon(logged_in_page: Page):
    """代替フロー:クーポン適用して購入する"""
    logged_in_page.goto("localhost:3000/cart")
    logged_in_page.fill("#coupon-input", "DISCOUNT10")
    logged_in_page.click("#apply-coupon-btn")
    # クーポン適用後の金額が正しいか確認
    expect(logged_in_page.locator(".discount-amount")).to_be_visible()

# ── 例外フロー ──────────────────────────────────
def test_purchase_payment_failure(logged_in_page: Page):
    """例外フロー:決済失敗時にエラーメッセージが表示されカートが保持される"""
    logged_in_page.goto("localhost:3000/cart")
    logged_in_page.click("#checkout-btn")
    # 無効なカード番号で決済
    logged_in_page.fill("#card-number", "0000000000000000")
    logged_in_page.click("#confirm-order-btn")
    # エラーメッセージが表示されるか
    expect(logged_in_page.locator(".payment-error")).to_be_visible()
    # カートの中身が保持されているか
    expect(logged_in_page.locator(".cart-badge")).to_have_text("1")
💡 実務Tip:基本フロー・代替フロー・例外フローを同じファイルにまとめることで「この商品購入ユースケースのテストは全部ここにある」という一覧性が生まれます。テストファイルの名前をユースケース名にすることで、どのシナリオをカバーしているかがファイル名から一目でわかります。

⚠️ ユースケーステストでよくある失敗パターン4選

実務でユースケーステストを設計するときに陥りやすい失敗を紹介します。

① 基本フロー(正常系)だけで終わらせてしまう

「商品を購入できること」だけ確認して終わりにしてしまうケースです。ユースケーステストの本来の価値は代替フロー・例外フローを洗い出すことにあります。「ゲスト購入は?」「クーポンは?」「決済失敗は?」と問いかけてフローを網羅しましょう。

② 1つのテスト関数に複数のユースケースを詰め込む

「登録→ログイン→購入→ログアウト」をすべて1つのテスト関数に書いてしまうケースです。どこで失敗したかが特定しづらくなり、前半のステップが失敗すると後半のテストが実行できなくなります。1ユースケース=1テスト関数の原則を守りましょう。

③ ユーザーの視点ではなくエンジニアの視点でシナリオを作る

「APIのパラメータをテストする」「DBに正しく保存されるか確認する」という視点で書かれたシナリオはユースケーステストではなく機能テストです。ユースケーステストでは「ユーザーが画面でどう操作するか」を起点にシナリオを書きます。ユーザーストーリー(「〜として、〜したい」)を参照しながら設計するのが効果的です。

④ すべてのユースケースを同じ優先度でテストしようとする

ユースケースの数が多い場合、すべてを同じ頻度でテストするのは非現実的です。「購入完了」「ログイン」などのコアユースケースは毎回、「パスワード変更」「住所変更」などは週次など、リスクと利用頻度に応じて優先度を付けることが実務では重要です。

FAQ

Q. ユースケーステストはどんなシステムに使うべきですか?

ユーザーが操作するUIを持つシステム全般に有効です。特にECサイト(購入・登録・検索)・予約システム(検索・予約・変更・キャンセル)・社内業務システム(申請・承認・却下)など、複数のステップからなる操作フローがあるシステムに最も効果的です。

Q. ユースケーステストと状態遷移テストの使い分けは?

ユースケーステストは「ユーザーのゴールへの一連の操作フロー」を検証します。状態遷移テストは「システムの状態と遷移が正しいか・無効遷移が拒否されるか」を検証します。実務では両方を組み合わせることが多く、ユースケーステストで正常フローを網羅しつつ、状態遷移テストで無効遷移を補完するという構成が一般的です。

Q. JSTQBでユースケーステストはどの程度出題されますか?

JSTQB Foundation Levelでは「ユースケーステストの概念・基本フローと代替フローの定義」が問われます。「ユースケースから導き出されるテストケースは基本フロー・代替フロー・例外フローを含む」という概念を理解しておけば対応できます。

実務では、ユーザーストーリー(「〜として、〜したい」)やプロダクトの要件定義書からユースケースを抽出し、それをPlaywright × pytestのE2Eテストに変換するワークフローがよく使われます。設計書とテストコードが1対1で対応するため、機能追加・変更時にどのテストを更新すべきかが一目でわかるメリットがあります。

📋 この記事のまとめ

  • ユースケーステストは「ユーザーのゴールへの操作フロー」を設計するテスト設計技法
  • 基本フロー・代替フロー・例外フローの3つを網羅することで、正常系から異常系まで体系的にカバーできる
  • 代替フロー・例外フローの洗い出しが最大のポイント。「ゲスト購入は?」「決済失敗は?」と問いかけ続ける
  • 1ユースケース=1テストファイルの構成がPlaywright × pytest実装のベストプラクティス
  • リスクと利用頻度に応じてユースケースの優先度を付けることが実務では重要

ユースケーステストの最大の価値は「ユーザーが実際に行う操作」を起点にすることで、単体テストでは発見できない「フローをまたいだバグ」を体系的に発見できる点です。まず身近なサービスの「商品を購入する」「会員登録する」というユースケースから基本フロー・代替フロー・例外フローを書き出してみましょう。

タイトルとURLをコピーしました