状態遷移テストの実践的な手法と効果的な活用ガイド
状態遷移テストは、「今どの状態か」によって同じ操作の結果が変わるシステムを検証する技法です。ログイン、申請フロー、決済ステータスのように、順序が結果を左右するものが対象になります。
実務で本当に効くのは、正常な遷移の確認ではありません。状態遷移表を作ったときに現れる「空白のマス」——仕様が定義していない操作を洗い出すことです。本番で最も痛い不具合は、たいていそこから出ます。
この記事では、図と表の作り方、0スイッチ/1スイッチ/Nスイッチという網羅基準の選び方、そして無効遷移の扱いまでを具体例で解説します。
状態遷移テストとは
システムが持つ「状態」と、状態を切り替える「イベント」の関係を検証します。
エレベーターなら「停止」「上昇中」「下降中」という状態があり、ボタン操作で切り替わります。この切り替わりが仕様どおりかを確認するのが目的です。
重要なのは、一見正しく動いているシステムでも、特定の順序で操作すると不整合が起きるという点です。静的なデータではなく、システムの「流れ」に注目する技法だと考えると分かりやすいと思います。
他の技法との違い
| 技法 | 見ているもの | 状態遷移テストとの違い |
|---|---|---|
| 同値分割・境界値分析 | 1つの入力項目の範囲 | 順序を扱わない |
| 決定表テスト | 条件の組み合わせと結果 | 「今の状態」しか扱えない |
| ペアワイズテスト | 設定項目の組み合わせ | 順序を扱わない |
| 状態遷移テスト | 状態とイベントの関係 | 順序が結果を変えるものを扱える |
決定表と混同しやすいので注意してください。 決定表は「条件がこうなら結果はこう」を定義しますが、「そこに至るまでの経路」は表現できません。「完了状態から申請中に戻せてしまう」といった不具合は、決定表では見つかりません。
状態遷移図の作り方
手順は3ステップです。
- 初期状態を決める(例:「消灯」)
- イベントを洗い出す(例:スイッチ操作、タイマー満了)
- 状態とイベントを矢印でつなぐ
家庭用照明を例にします。
スイッチON 調光ボタン押下
[消灯] ──────────────→ [点灯] ──────────────→ [調光モード]
↑ │ │
│ スイッチOFF │ │
└─────────────────────┘ │
│ │
│ タイマー満了 │
└──────────────────────────────────────────────┘
図の目的は「全体像を一目で見ること」です。 状態が5つを超えると図は読みづらくなるので、その場合は次の表を主役にしてください。
状態遷移表:ここが本番
図では「描かれていない矢印」に気づけません。 表にすると、抜けが構造的に見えます。
作り方は単純で、縦に「現在の状態」、横に「イベント」を並べ、すべてのマスを埋めるだけです。
| 現在の状態\イベント | スイッチON | スイッチOFF | 調光ボタン | タイマー満了 |
|---|---|---|---|---|
| 消灯 | 点灯 | ? | ? | ? |
| 点灯 | ? | 消灯 | 調光モード | 消灯 |
| 調光モード | ? | ? | ? | 消灯 |
「?」のマスが、仕様書に書かれていない操作です。 状態3つ × イベント4つ = 12マスのうち、埋まっているのは5つしかありません。
ここで開発者に確認すべきことが明確になります。
- 消灯中にスイッチOFFを押したらどうなるか(何も起きないのか、エラーか)
- 点灯中にスイッチONを押したらどうなるか(無視か、明るさ変化か)
- 調光モード中に調光ボタンをもう一度押したら(点灯に戻るのか、循環するのか)
状態遷移テストの価値の大半は、この表を作る過程にあります。 テスト実行より前の、仕様レビューの段階で効きます。上流での使い方はウォーターフォール開発におけるQAの重要性にまとめています。
網羅基準:0スイッチ・1スイッチ・Nスイッチ
どこまでテストするかを決める基準です。ここを決めずに始めると、ケース数が担当者ごとにばらつきます。
| 基準 | 確認するもの | ケース数 |
|---|---|---|
| 0スイッチ | 1回の遷移をすべて(各矢印を1度ずつ) | 矢印の数だけ |
| 1スイッチ | 連続する2回の遷移の組み合わせ | 大幅に増える |
| Nスイッチ | 連続する N+1 回の遷移 | 指数的に増える |
用語に注意してください。 「0スイッチ」は「状態を1度ずつ訪れる」ことではなく、「1回の遷移をすべて通す」ことです。スイッチの数は「連続する遷移の“つなぎ目”の数」を指します。
具体例
0スイッチ:消灯 →(ON)→ 点灯 ← 矢印1本ずつを確認
1スイッチ:消灯 →(ON)→ 点灯 →(調光)→ 調光モード ← 2本つなげて確認
1スイッチで初めて見つかる不具合があります。 「単独では正しく動くが、直前の状態によって挙動が変わる」というケースです。内部にフラグを持っている実装でよく起きます。
実務での選び方
基本は0スイッチ、リスクの高い箇所だけ1スイッチが現実的です。
- 0スイッチ:まず全部の矢印を通す。ここは必須
- 1スイッチ:決済、権限変更、データ削除など、壊れたときの影響が大きい経路に絞る
- Nスイッチ(N≥2):組み込み機器など、極めて高い信頼性が要求される場合のみ
1スイッチを全経路に適用するとケース数が現実的でなくなります。 私も、全網羅を目指して見積もりが破綻しかけた経験があります。どこを厚くするかを先に決めてください。
無効遷移こそテストする
「起こり得ないはず」の操作こそ、本番で起きます。
ブラウザの戻るボタン、二重クリック、複数タブでの同時操作、通信断からの復帰——いずれもユーザーが意図せず無効な遷移を発生させる経路です。
確認すべきパターン
| パターン | 具体例 |
|---|---|
| 完了後の再操作 | 承認済みの申請を、戻るボタンで開いて再度承認する |
| 二重実行 | 送信ボタンを連打する |
| 並行操作 | 2つのタブで同じ申請を別々に操作する |
| 途中中断 | 処理中に通信が切れる。データはどの状態で残るか |
| 権限の変化 | 承認待ちのまま、承認者のアカウントが削除される |
期待結果は「エラーになること」ではなく「どうエラーになるか」まで決めてください。 画面にメッセージが出るのか、無視されるのか、前の画面に戻るのか。これが曖昧だと、実装者ごとに挙動がばらつきます。
表への書き方
無効遷移はマスを空欄にせず、明示的に埋めます。
| 現在の状態\イベント | 承認する | 差し戻す |
|---|---|---|
| 申請中 | 承認済み | 下書き |
| 承認済み | 変化なし+「すでに承認済みです」を表示 | 変化なし+操作不可 |
| 下書き | 変化なし+ボタン非表示 | 変化なし+ボタン非表示 |
「―」や空欄で済ませないことが重要です。 空欄は「決まっていない」と同義になります。
人が起こさないイベントを忘れない
状態を変えるのはユーザー操作だけではありません。ここが抜けると、時間が経ってから起きる不具合を取り逃します。
- タイマー・バッチ処理:セッション期限切れ、自動キャンセル、日次バッチ
- 外部システムからの通知:決済のWebhook、在庫連携
- センサー入力:IoT機器の状態変化
- 他ユーザーの操作:自分が編集中に、別の管理者が同じデータを変更する
「予約が自動キャンセルされた直後に、ユーザーが決済を完了した」——こうした競合はテスト設計で意識しないと再現できません。
適用が向くシステム
| 対象 | 状態の例 |
|---|---|
| 申請・承認フロー | 下書き / 申請中 / 承認済み / 差し戻し |
| 注文・決済 | カート / 決済待ち / 決済済み / 発送済み / キャンセル |
| 認証 | 未ログイン / ログイン中 / ロック中 / セッション切れ |
| メディア再生 | 停止 / 再生中 / 一時停止 / バッファ中 |
| IoT機器 | 接続待ち / 接続中 / スリープ / エラー |
逆に、状態を持たない検索やフィルタのような機能には向きません。そこは同値分割や決定表の担当です。
E2Eテストとの関係
状態遷移テストで洗い出した経路は、そのままE2Eテストの対象候補になります。ただし全部を自動化すべきではありません。
- 0スイッチの主要経路:E2Eで自動化する価値が高い
- 無効遷移:単体テストやAPIテストで確認する方が安定する
- 1スイッチの全網羅:自動化しても保守コストが見合わないことが多い
何を自動化するかの判断軸はE2Eで「守るべきもの」はこう決めるにまとめました。
まとめ
- 状態遷移テストは順序が結果を左右するシステムを扱う。決定表は「今の状態」しか扱えない
- 価値の大半は状態遷移表を作る過程にある。 空白のマス=仕様の抜け
- 「0スイッチ」は1回の遷移をすべて通すこと。状態を1度ずつ訪れることではない
- 基本は0スイッチ、影響の大きい経路だけ1スイッチ。 全経路の1スイッチは破綻する
- 無効遷移は空欄にせず、「どうエラーになるか」まで書く
- 戻るボタン・二重クリック・複数タブは、無効遷移が実際に起きる経路
- タイマーや外部通知など、人が起こさないイベントを忘れない
- 洗い出した経路のうち、E2Eで自動化するのは主要経路に絞る
「システムの動きそのもの」を追う技法なので、画面仕様書を読んでいるだけでは気づけない抜けが見つかります。表を1枚作るところから始めてみてください。