デシジョンテーブルテストとは?作り方と実例を解説|条件の組み合わせ・pytest実装

テスト自動化

デシジョンテーブルテストとは、複数の条件とその組み合わせを表形式で整理してテストケースを設計する技法です。ログイン処理・権限管理・割引ロジックなど、複数条件が絡む業務ルールの検証で特に効果を発揮します。

デシジョンテーブルを使うと、複数条件の組み合わせを漏れなく・ダブりなく整理でき、「あの組み合わせをテストし忘れた」という問題を根本から防ぐことができます。

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

  • デシジョンテーブルテストを初めて学ぶQAエンジニア・開発者
  • 複数条件の組み合わせテストをどう整理すればいいか悩んでいる方
  • 業務ロジック・権限管理のテストを体系化したい方
  • JSTQBの学習でデシジョンテーブルを理解したい方

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

  • デシジョンテーブルの概念と作り方がわかる
  • 実務でよく出るログイン・権限管理への適用方法がわかる
  • pytestのparametrizeとの組み合わせで自動テストに活かせる

👤 この記事を書いた人

QAエンジニア・テスト自動化エンジニアとして15年以上の実務経験を持つ Yoshi が執筆。デシジョンテーブルは業務ロジックの複雑なテスト設計で毎日活用している技法です。実装コードはGitHubで公開中:github.com/YOSHITSUGU728/automated-testing-portfolio

「条件が2つ以上絡み合うと、どの組み合わせをテストすべきかわからなくなる」——こうした悩みはQAエンジニアなら誰でも経験することです。

  • 条件が増えるたびにテストケースが爆発的に増える
  • どの組み合わせをテストしたか・していないかが曖昧になる
  • 「あのパターン、テストしてなかった」という見落としが起きる

デシジョンテーブルテストはこうした問題を解決する技法です。この記事では概念から具体的な作り方・pytestへの応用まで一気通貫で解説します。

📌 結論

  • 条件を縦軸・ケースを横軸に表形式で整理し、全組み合わせを一覧化するテスト設計技法
  • 条件2個=4パターン、3個=8パターンが基本だが、不可能な組み合わせは削除して効率化できる
  • pytestの parametrize に渡すことで、設計した表をそのまま自動テストに変換できる

デシジョンテーブルテストとは?

デシジョンテーブルテストは、「条件(入力)」と「アクション(期待結果)」の関係を表形式で整理するテスト設計技法です。条件の組み合わせを体系的に整理できるため、複雑な業務ロジックのテストで広く使われています。「決定表テスト」とも呼ばれます。

例えば「ユーザーの種別(一般/プレミアム)」と「クーポンの有無(あり/なし)」という2つの条件が絡む割引処理をテストする場合、デシジョンテーブルを使えば4パターン(2×2)すべてを漏れなく整理できます。

比較項目デシジョンテーブルなしデシジョンテーブルあり
組み合わせの管理頭の中・箇条書きで管理表で一目見て全パターンわかる
見落としリスク高い(抜け漏れが起きやすい)低い(表で網羅性が保証される)
チームへの共有口頭説明が必要・曖昧になりがち表をそのまま共有・レビューしやすい
自動テストへの変換設計とコードが分離しがちparametrizeにそのまま使える

デシジョンテーブルの構造と作り方

デシジョンテーブルは「条件部」と「アクション部」の2つのパートで構成されます。

📋 デシジョンテーブルの基本構造

ケース1ケース2ケース3ケース4
【条件部 Conditions】
ID 正しい?YYNN
PW 正しい?YNYN
【アクション部 Actions】
ログイン成功

💡 読み方のポイント

  • 縦軸:条件(入力)とアクション(期待結果)
  • 横軸:テストケース番号
  • Y/N:各条件が真か偽か
  • ✅/❌:そのケースでアクションが発生するか
  • 条件 2個 → 4ケース(2²)が基本
パート内容
条件部(Conditions)テストする入力条件IDが正しい? / パスワードが正しい?
アクション部(Actions)条件の組み合わせに対応する期待結果ログイン成功 / エラー表示

デシジョンテーブルのメリット

  • 条件の組み合わせを漏れなく整理できる:全パターンが表に並ぶため見落としが防げる
  • テストケースの見落としを防げる:「なんとなくテスト」から「網羅的なテスト」へ変わる
  • チームレビューがしやすい:表形式でQAと開発が共通認識を持てる
  • 自動テストへ変換しやすい:pytestの parametrize にそのまま渡せる

作り方の手順

ステップ内容
STEP 1仕様書から「条件」を洗い出す(Yes/Noで答えられる形にする)
STEP 2条件の数から全パターン数を計算する(条件n個 = 2ⁿパターン)
STEP 3各パターンに対応するアクション(期待結果)を記入する
STEP 4実際には発生しない組み合わせ(不可能なケース)を除外して削減する
💡 条件数とパターン数の目安:条件がすべて Yes/No(真偽)の場合、条件 n 個で 2ⁿ パターンになります。条件2個=4パターン・3個=8パターン・4個=16パターン・5個=32パターン。条件が6個以上になる場合はペアワイズテストの活用を検討しましょう。

実例①:ログイン処理のデシジョンテーブル

最もよく使われる例として、ログイン処理のデシジョンテーブルを作ってみます。条件は「IDが正しいか」「パスワードが正しいか」の2つです。

条件 / アクションケース1ケース2ケース3ケース4
条件①:IDが正しいYesYesNoNo
条件②:パスワードが正しいYesNoYesNo
アクション:ログイン成功
アクション:エラーメッセージ表示

このテーブルから 4つのテストケースが明確に導き出せます。ケース2・3・4はすべてエラーになりますが、エラーメッセージの内容(IDが間違い / パスワードが間違い / 両方間違い)が異なる場合もあるため、3件とも実施することをおすすめします。

実例②:割引ロジックのデシジョンテーブル(条件3つ)

条件が3つになるとパターンは8通りに増えます。「会員種別(プレミアム)」「クーポン利用」「購入金額(3,000円以上)」の3条件で割引率を決めるロジックを例にします。

条件 / アクションC1C2C3C4C5C6C7C8
プレミアム会員YYYYNNNN
クーポンありYYNNYYNN
3,000円以上YNYNYNYN
→ 割引率30%25%20%15%15%10%5%0%

このテーブルを一見すると、C4(プレミアム・クーポンなし・3,000円未満=15%)とC5(非プレミアム・クーポンあり・3,000円以上=15%)が同じ割引率になっているのがわかります。こうした「同じ結果になるケース」を発見してテスト数を削減するのもデシジョンテーブルの効果です。

💡 実務Tip:同じアクション(期待結果)になるケースは統合してテスト数を減らせます。C4とC5を1ケースにまとめると8ケース→7ケースに削減できます。ただし、エラーメッセージの内容が異なる可能性がある場合は統合しない方が安全です。

pytestへの応用

デシジョンテーブルで設計したテストケースは、pytestの @pytest.mark.parametrize にそのまま渡せます。以下はログイン処理のデシジョンテーブルをpytestで実装した例です。

まず、テスト対象のログイン関数を用意します。

def login(user_id: str, password: str) -> dict:
    """ログイン処理(サンプル)"""
    VALID_ID = "test_user"
    VALID_PW = "secret_pass"

    if user_id == VALID_ID and password == VALID_PW:
        return {"success": True, "message": "ログイン成功"}
    elif user_id != VALID_ID:
        return {"success": False, "message": "IDが存在しません"}
    else:
        return {"success": False, "message": "パスワードが正しくありません"}

次に、デシジョンテーブルの4ケースをそのままパラメータとして実装します。

import pytest

# デシジョンテーブルの4ケースをそのままパラメータ化
@pytest.mark.parametrize("user_id, password, expected_success, expected_msg", [
    # ケース1:ID正しい・PW正しい → 成功
    ("test_user", "secret_pass", True,  "ログイン成功"),

    # ケース2:ID正しい・PW間違い → 失敗
    ("test_user", "wrong_pass",  False, "パスワードが正しくありません"),

    # ケース3:ID間違い・PW正しい → 失敗
    ("wrong_user", "secret_pass", False, "IDが存在しません"),

    # ケース4:ID間違い・PW間違い → 失敗
    ("wrong_user", "wrong_pass",  False, "IDが存在しません"),
])
def test_login(user_id, password, expected_success, expected_msg):
    result = login(user_id, password)
    assert result["success"] == expected_success
    assert result["message"] == expected_msg

実行結果サンプル

$ pytest test_login.py -v

========================= test session starts ==========================
collected 4 items

test_login.py::test_login[test_user-secret_pass-True-ログイン成功]         PASSED [ 25%]
test_login.py::test_login[test_user-wrong_pass-False-パスワードが正しくありません] PASSED [ 50%]
test_login.py::test_login[wrong_user-secret_pass-False-IDが存在しません]    PASSED [ 75%]
test_login.py::test_login[wrong_user-wrong_pass-False-IDが存在しません]     PASSED [100%]

========================== 4 passed in 0.12s ===========================
💡 実務Tip:デシジョンテーブルを先にスプレッドシートや表で作成し、それをそのままコードに落とし込む流れが実務のベストプラクティスです。コメントに「ケース1〜4」を記載しておくと、後からテーブルとコードの対応関係が追いやすくなります。

⚠️ デシジョンテーブルテストでよくある失敗パターン4選

実務でデシジョンテーブルを作るときに陥りやすい失敗を紹介します。

① 条件を Yes/No に落とし込まずにテーブルを作る

デシジョンテーブルの条件は必ず「Yes/No(真/偽)」で答えられる形にします。「ユーザー種別」のように複数の値を取る条件は「プレミアム会員か?(Yes/No)」に変換してから使います。条件を整理せずにテーブルを作ると、パターンの計算が狂って見落としが生まれます。

② 不可能な組み合わせを削除し忘れてテストが増えすぎる

例えば「クーポン適用済み」と「クーポンコード未入力」は同時に起きえない組み合わせです。こうした不可能なケースを削除しないと、テスト数が必要以上に増えてしまいます。テーブルを作ったら必ず「現実に起きうるか?」を確認してから不可能なケースを除外しましょう。

③ 同じ結果になるケースをむやみに統合してエラーの違いを見落とす

アクション(期待結果)が同じでも、エラーメッセージの内容や後続処理が異なる場合があります。「どちらもエラーになる」だけを見てケースを統合すると、「IDが間違い」と「パスワードが間違い」で異なるメッセージが出るべきなのに見落としてしまいます。統合する前に期待結果の詳細まで確認しましょう。

④ 条件が6個以上でテーブルが巨大になりすぎる

条件が6個になると64パターン、7個では128パターンになります。この規模になるとデシジョンテーブルだけでは管理しきれません。条件が5個以上の場合はペアワイズテストと組み合わせてパターン数を削減するか、条件をグループに分けて複数のテーブルに分割することを検討しましょう。

FAQ

Q. デシジョンテーブルはいつ使うべきですか?

デシジョンテーブルは、複数の条件が組み合わさって結果が決まる処理のテスト設計に適しています。例えばログイン認証・権限管理・料金計算・割引ロジックなどです。条件が1つだけの場合は同値分割や境界値分析の方がシンプルに設計できます。

Q. デシジョンテーブルとペアワイズテストの違いは?

デシジョンテーブルは「すべての条件の組み合わせ」を整理する技法です。一方、ペアワイズテストは「条件のペアを最低1回ずつテストする」ことでテストケース数を削減する技法です。条件が5個以上になる場合は、デシジョンテーブル単独ではパターン数が爆発するため、ペアワイズテストとの併用が実務ではよく行われます。

Q. デシジョンテーブルと同値分割・境界値分析はどう使い分けますか?

同値分割・境界値分析は「1つの入力フィールドの値の範囲」を検証するときに使います。デシジョンテーブルは「複数の条件の組み合わせ」を検証するときに使います。実務では両方を組み合わせることが多く、例えばフォームの各フィールドには同値分割・境界値分析を使いつつ、業務ロジックにはデシジョンテーブルを使うという構成が一般的です。

Q. 条件が Yes/No の2値でない場合はどうすればいいですか?

「会員ランク:一般・シルバー・ゴールド」のように3値以上の場合は、「シルバー以上か?(Yes/No)」「ゴールドか?(Yes/No)」のようにYes/No形式の条件に分解します。または、3値の場合は3列(一般・シルバー・ゴールド)として縦に並べる形式のテーブルも有効です。

Q. デシジョンテーブルはいつ作るべきですか?

「仕様書を読んで if/else や switch 文が複数絡み合っていると感じたとき」がデシジョンテーブルを作るサインです。特に業務ルール・権限管理・料金計算・割引ロジックなど、複数の条件が組み合わさって結果が変わる処理に適用すると効果的です。

Q. JSTQBのデシジョンテーブルはどの程度理解すれば合格できますか?

JSTQB Foundation Levelでは「デシジョンテーブルの読み方と基本的な作り方」が問われます。この記事のログイン処理の例(条件2個・4パターン)レベルが確実に理解できていれば合格ラインです。条件の数からパターン数を計算できること(条件n個=2ⁿ)も押さえておきましょう。

実務では、デシジョンテーブルをスプレッドシートで作成し、レビュー後にpytestの parametrize に変換するワークフローがよく使われます。設計と実装を分離できるため、QAチームと開発チーム双方でレビューしやすくなるメリットがあります。

📋 この記事のまとめ

  • デシジョンテーブルは条件(縦軸)×ケース(横軸)で全組み合わせを一覧化する技法
  • 条件n個=2ⁿパターンが基本で、不可能・重複ケースを削除してテスト数を最適化できる
  • ログイン・権限管理・割引ロジックなど複数条件が絡む業務ルールに特に有効
  • pytest parametrize との相性が抜群で、設計テーブルをそのまま自動テストに変換できる
  • 条件が5個以上になったらペアワイズテストとの組み合わせを検討する

デシジョンテーブルは「頭の中でなんとなく考えていた組み合わせ」を可視化して、見落としをゼロに近づける技法です。まずは身近なログイン処理や権限チェックに2〜3条件のテーブルを作ることから始めてみましょう。

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