状態遷移図と状態遷移テストとは?書き方とテストケース設計の手順

「ログイン中なのにもう一度ログイン画面が出る」「キャンセル済みの注文が発送されてしまった」——このような不具合は、機能単体のテストではまず見つかりません。原因が個々の機能ではなく、システムが取りうる「状態」とその移り変わりの設計にあるからです。
この「状態の移り変わり」を整理するための道具が状態遷移図です。それをテスト設計に落とし込む技法が状態遷移テストです。
本記事では、次の3つを順に解説します。
- 状態遷移図の構成要素と書き方
- 状態遷移表(状態遷移マトリクス)の作り方
- テスト技法としての状態遷移テスト(0スイッチ/1スイッチ/Nスイッチカバレッジ、無効遷移のテスト)
ECサイトの注文ステータスという具体例で、図・表・テストケース一覧まで一気通貫に説明します。
状態遷移図とは?システムの「状態の移り変わり」を可視化する図
状態遷移図(State Transition Diagram)とは、システムが取りうる「状態」を丸や四角で表し、状態どうしを矢印で結んだ図です。矢印には「どのイベントが起きたときにどの状態へ移るか」を書き添えます。
日本語では状態遷移図、UMLの文脈ではステートマシン図(State Machine Diagram)と呼ばれます。
ポイントは、「今どの状態にいるか」によって同じ入力でも振る舞いが変わることを表現できる点です。「入力に対する出力」だけを見る図とは、ここが違います。
たとえば同じ「再生ボタンを押す」という操作でも、停止中なら再生が始まります。再生中なら何も起きない(あるいは一時停止する)。直前までの履歴が結果を左右します。
この「履歴に依存する振る舞い」こそ、仕様書の文章だけでは抜け漏れが起きやすい領域です。
状態遷移図が必要とされる場面
状態遷移図が力を発揮するのは、次のようなシステムや機能を扱うときです。
- ECサイトの注文ステータス(未払い・支払済・発送済・キャンセルなど)
- 会員のログイン状態やアカウントのロック・凍結の管理
- ワークフロー/申請承認システム(起票・承認待ち・差戻し・承認済み)
- 動画・音楽プレイヤーやゲームなど、モードが切り替わるUI
- 組み込み機器の電源モード、通信プロトコルのコネクション管理
- 予約システムの予約ステータス(仮予約・確定・変更・取消)
いずれも共通するのは、「今の状態」がデータとして保持され、次に何ができるかを制限しているという構造です。この構造がある機能では、状態遷移図を書かないままテスト設計に入ると、必ずと言っていいほど遷移の考慮漏れが残ります。
状態遷移図の構成要素
状態遷移図は、次の6つの要素で構成されます。まずここを正確に押さえておくと、以降の状態遷移表やテストケース設計がスムーズに進みます。
| 構成要素 | 意味 | 図での表現 | 例(ECの注文) |
|---|---|---|---|
| 状態(State) | システムが取りうる、ある期間持続する状況 | 角丸四角形 | 未払い、支払済、発送済 |
| イベント(Event) | 状態変化のきっかけとなる出来事・操作・信号 | 矢印に添える文字 | 入金、出荷指示、キャンセル要求 |
| 遷移(Transition) | あるイベントによって状態が移ること | 状態から状態への矢印 | 未払い → 支払済 |
| アクション(Action) | 遷移の際に実行される処理・副作用 | イベントの後に「/処理名」 | 入金/注文確定メール送信 |
| ガード条件(Guard) | 遷移が成立するための追加条件 | [条件]で併記 | [入金額 = 請求額] |
| 初期状態/終了状態 | 開始点と、そこから先へ進まない終点 | 黒丸/二重丸 | 初期=未払い、終了=完了・キャンセル |
特に見落とされやすいのがガード条件です。「入金イベントが起きたら支払済に遷移する」と書いてしまいがちです。実際には「入金額が請求額以上のとき」だけ支払済へ進み、不足していれば未払いのまま、というケースは珍しくありません。
ガード条件は、同じイベントから複数の遷移先が分岐する場所です。バグが集中するポイントでもあります。
状態遷移図とUMLステートマシン図の関係
実務では「状態遷移図」と「UMLステートマシン図」がほぼ同じ意味で使われますが、厳密には次のような関係です。
- 状態遷移図:状態と遷移を表す図の総称。記法は現場ごとに自由度が高い。
- UMLステートマシン図:UML(統一モデリング言語)で標準化された状態遷移図の記法。初期状態は黒丸、終了状態は二重丸、遷移ラベルは「イベント[ガード]/アクション」という形式で書く、といった書き方が定義されている。
UMLステートマシン図には、拡張表現もあります。複数の状態をまとめる合成状態(サブステート)、複数の状態機械を同時に動かす直交状態、直前の状態に戻るヒストリ擬似状態などです。
テスト設計が目的なら、いきなり高度な記法を使うと関係者が読めなくなります。まずは「状態・イベント・遷移」の3要素だけのシンプルな図から始めるのが現実的です。
状態遷移図は「開発者のための設計図」であると同時に「テスト設計のインプット」でもあります。設計工程の成果物をテスト設計に活かす考え方は、Vモデルの基本そのものです。詳しくはVモデルとは?特徴と実務での活用方法もあわせてご覧ください。
状態遷移図の書き方【4ステップ】
状態遷移図はいきなり作図ツールを開いて書き始めると、たいてい途中で破綻します。次の4ステップで、「洗い出し」と「作図」を分けて進めるのが確実です。
ステップ1:状態を洗い出す
まず、対象システムが取りうる状態をすべて書き出します。このとき有効なのが、DBのステータスカラムや画面表示の切り替え条件を根拠にすることです。仕様書の文章から拾うだけでなく、実装側の「ステータス値の一覧」を突き合わせると、仕様書に書かれていない中間状態(例:与信中、返金処理中)が見つかります。
状態の粒度も重要です。細かくしすぎると図が爆発し、粗くしすぎると遷移の違いを表現できません。
判断基準は「その2つを区別しないと、同じイベントに対する振る舞いを説明できなくなるか」です。説明できなくなるなら分ける、できるなら1つにまとめます。
ステップ2:イベントを洗い出す
次に、状態を変化させうるイベントを列挙します。ユーザー操作だけでなく、次の観点を必ず含めてください。
- ユーザー操作:ボタン押下、フォーム送信、画面遷移
- 外部システムからの通知:決済代行からの入金通知、配送業者のステータス連携
- 管理者・オペレーターの操作:管理画面からの強制キャンセル、ステータス手動変更
- 時間経過:支払期限切れ、セッションタイムアウト、自動キャンセル
- 異常系:通信エラー、処理失敗によるロールバック
特に時間経過イベントと管理者操作イベントは抜けやすい代表格です。「ユーザーが何もしなくても状態が変わるケースはないか」「運用担当が手で直すケースはないか」を必ず確認しましょう。
ステップ3:遷移を定義する
洗い出した状態とイベントを掛け合わせ、「状態Aでイベントxが起きたら状態Bへ移る」という組み合わせを定義していきます。ここで同時に、遷移時のアクション(メール送信、在庫引当、ログ記録など)とガード条件も記述します。
この段階では図に描かず、箇条書きや表で網羅的に洗い出すのがコツです。図に描いてしまうと「描いた矢印」しか目に入らなくなり、描かれなかった組み合わせが視界から消えてしまうためです。次章の状態遷移表は、まさにこの問題を解決するための道具です。
ステップ4:図に落とし込む
最後に、状態を角丸四角、遷移を矢印として配置します。作図時のポイントは次のとおりです。
- 初期状態を左上または上部に置き、正常系の流れを左から右(または上から下)へ一直線に並べる
- 異常系・キャンセル系の遷移は正常系の下側にまとめ、矢印が交差しないように配置する
- 矢印のラベルは「イベント名[ガード条件]/アクション名」で統一する
- 状態が10個を超えたら、機能単位で図を分割するか合成状態でまとめる
状態遷移表(状態遷移マトリクス)の作り方
状態遷移表(状態遷移マトリクス)とは、行に状態、列にイベントを並べ、交差するセルに「遷移先の状態」を書き込んだ表です。状態遷移図とまったく同じ情報を、表という別の形式で表現したものだと考えてください。
状態遷移表の基本構造
状態がm個、イベントがn個あれば、表のセルは必ずm×n個になります。この「必ず m×n 個になる」という性質が、状態遷移表の最大の価値です。
図では見落とす「起こりえない遷移」「未定義の遷移」が表にすると可視化される
ここが状態遷移表を作る最大の理由です。
状態遷移図は「起こる遷移」だけを矢印で描きます。裏を返せば、「本来定義すべきなのに誰も気づかず定義されていない遷移」は、図の上では何も描かれないため存在すら認識できません。矢印が描かれていない箇所は「起こらない」のか「考慮漏れ」なのか、図を見ただけでは区別がつかないのです。
状態遷移表なら、すべての「状態×イベント」の組み合わせがセルとして必ず出現します。空白のセルが残っていれば、それは検討していない組み合わせが存在するという明確なシグナルです。
埋まっていないセルは、次の3種類に分類していきます。
| セルの種類 | 記号例 | 意味 | テストでの扱い |
|---|---|---|---|
| 有効な遷移 | 遷移先の状態名 | そのイベントで別状態へ移る | 正常系として必ずテストする |
| 自己遷移・無視 | 「-」または同じ状態名 | イベントは受け付けるが状態は変わらない | 状態が変わらないことを確認する |
| 起こりえない遷移(無効遷移) | 「✕」 | 仕様上、そのイベント自体が発生しえない/禁止されている | 無効遷移テストで「起きないこと」を確認する |
| 未定義の遷移 | 空白のまま | 仕様として検討されていない=仕様の抜け | テスト前に仕様確認へ差し戻す |
実務でもっとも価値があるのは4つ目の「未定義の遷移」の発見です。これはバグではなく仕様の欠落であり、テスト実行前の設計レビュー段階で潰せるため、修正コストが桁違いに小さくて済みます。状態遷移表を作る目的の半分は、この仕様の抜けを早期に炙り出すことにあると言っても過言ではありません。
状態遷移図と状態遷移表の使い分け
| 観点 | 状態遷移図 | 状態遷移表 |
|---|---|---|
| 得意なこと | 全体の流れ・経路の直感的な把握 | 組み合わせの網羅性の確認 |
| 苦手なこと | 描かれていない組み合わせの発見 | 経路の流れを直感的に追うこと |
| 規模が大きいとき | 矢印が交差して読めなくなる | セル数が増えるが構造は崩れない |
| 主な用途 | 関係者との仕様合意、設計レビュー | 仕様の抜け漏れ検出、テストケース抽出 |
| 作成順序 | 先に書いて全体像をつかむ | 後から作って網羅性を検証する |
結論として、どちらか一方ではなく両方作るのが正解です。図で全体像を関係者と合意し、表で抜け漏れを検証する。この2段構えが、状態に起因する不具合をもっとも効率よく減らします。
状態遷移テスト(State Transition Testing)とは
状態遷移テストとは、状態遷移図・状態遷移表をもとにテストケースを導出する、ブラックボックステスト技法のひとつです。ISTQB/JSTQBのシラバスでも、同値分割法・境界値分析・デシジョンテーブルテストと並ぶ代表的なテスト技法として位置づけられています。
他のテスト技法との位置づけの違い
ブラックボックステスト技法は、それぞれ着目する「バグの原因」が異なります。
- 同値分割・境界値分析:ひとつの入力値の範囲に起因するバグを狙う
- デシジョンテーブル・ペアワイズ法:複数の条件の組み合わせに起因するバグを狙う
- 状態遷移テスト:操作の「順序」と「履歴」に起因するバグを狙う
状態遷移テストは、他の技法では原理的に見つけられない種類のバグを担当します。境界値分析やペアワイズ法をどれだけ丁寧にやっても、「キャンセル後に発送処理が通ってしまう」というバグは検出できません。
技法は競合ではなく補完関係にあると理解してください。テスト技法全体の見取り図はシステムテストの種類一覧で整理しています。
Nスイッチカバレッジという考え方
状態遷移テストの網羅度を測る指標がNスイッチカバレッジです。「スイッチ」とは遷移の切り替わりを指し、連続する(N+1)本の遷移の並びをどこまで網羅するかを表します。ここが状態遷移テストのもっとも実務的な部分であり、多くの解説記事が触れていない領域でもあります。
| カバレッジ | 網羅の単位 | 意味 | ケース数の目安 | 見つかるバグの例 |
|---|---|---|---|---|
| 0スイッチ(N=0) | 遷移1本 | すべての有効な遷移を最低1回ずつ通す | 有効遷移の本数と同じ | そもそも遷移しない、遷移先が違う |
| 1スイッチ(N=1) | 連続する遷移2本 | 「遷移A → 遷移B」の組み合わせをすべて通す | 0スイッチの2〜5倍程度 | 直前の遷移の影響で次の遷移が壊れる |
| 2スイッチ(N=2) | 連続する遷移3本 | 「遷移A → B → C」の組み合わせをすべて通す | さらに数倍に増加 | 3手先で状態が壊れる、内部データの蓄積不整合 |
| Nスイッチ | 連続する遷移(N+1)本 | より長い操作シーケンスを網羅 | 指数的に増加 | 長時間運用で顕在化する不整合 |
0スイッチカバレッジ:すべての遷移を1回ずつ通す
0スイッチカバレッジは、状態遷移図に描かれた矢印を1本残らず1回以上通すことを目標とします。「全遷移網羅」とも呼ばれ、状態遷移テストの最低ラインです。
ここで注意したいのが、「すべての状態を1回ずつ通す(全状態網羅)」では不十分だという点です。全状態を訪れるだけなら、遷移の一部を通らずにゴールできてしまいます。
状態ではなく遷移(矢印)を数える。これが0スイッチカバレッジの本質です。コードカバレッジにおける命令網羅(C0)と分岐網羅(C1)の関係とよく似ています(参考:C0・C1・C2カバレッジの違い)。
1スイッチカバレッジ:連続する2つの遷移の組み合わせを網羅する
1スイッチカバレッジでは、「ある遷移の直後に、次のどの遷移が来ても正しく動くか」を確認します。0スイッチでは各遷移をバラバラに1回通せば合格ですが、1スイッチでは遷移のペアをすべて作る必要があります。
実装上のバグには「直前にどの経路を通ってその状態に来たか」で振る舞いが変わるものが多くあります。これが1スイッチを重視する理由です。
たとえば「支払済」という同じ状態でも、通常決済で到達した場合とポイント全額利用で到達した場合とで内部フラグが異なります。次の出荷処理で、片方だけ失敗するというケースです。
0スイッチでは各遷移を1回ずつ通せば済みます。こうしたバグは高い確率ですり抜けます。
Nスイッチはどこまで上げるべきか
Nを上げれば網羅性は高まりますが、テストケース数は指数的に増加します。実務での判断基準は次のとおりです。
- 0スイッチは必須。状態を持つ機能で全遷移を通していないなら、それはテスト設計が不完全な状態です。
- 1スイッチは、状態が業務・金銭に直結する領域で適用。決済、在庫引当、権限管理、契約ステータスなど。
- 2スイッチ以上は限定的に。過去に順序起因の障害が発生した箇所、人命や大きな損害に関わる組み込み機器などに絞り、全体には適用しない。
「全体は0スイッチ、リスクの高い状態まわりだけ1スイッチ」というメリハリのある設計が、費用対効果としてはもっとも優れています。
無効遷移のテスト:起きてはいけない遷移が起きないことを確認する
0スイッチも1スイッチも、「起こるべき遷移が正しく起こるか」を確認するものです。実務で本当に痛い障害は、むしろ逆側で起きます。
- キャンセル済みの注文に対して出荷処理が通り、商品が発送されてしまう
- ロックされたアカウントでログインが成功してしまう
- 承認済みの申請が、差戻しボタンの連打で二重に差し戻される
- ブラウザの戻るボタンで前の画面に戻り、完了済みの処理が再実行される
これらはすべて無効遷移(起こってはいけない遷移)が実際に起きてしまったケースです。無効遷移のテストでは、状態遷移表で「✕」を付けたセルに対して、意図的にイベントを発生させます。
確認するのは状態が変わらないこと・適切なエラーが返ること・データが壊れないことの3点です。
画面上でボタンが非活性になっていても、無効遷移を起こす経路は残っています。
- URLの直接入力
- APIの直接呼び出し
- ブラウザの戻る操作
- 二重送信
- 他端末からの同時操作
「画面上で押せないから起きない」は根拠になりません。サーバー側で状態をチェックしているかどうかを、APIレベルで確認する必要があります。
具体例:ECサイトの注文ステータスで図・表・テストケースを一気通貫で作る
ここまでの内容を、ECサイトの注文ステータスという具体例で通しで作ってみます。
対象の仕様
状態は5つ、イベントは4つとします。
| 種別 | ID | 名称 | 説明 |
|---|---|---|---|
| 状態 | S1 | 未払い | 注文確定済み、入金待ち(初期状態) |
| 状態 | S2 | 支払済 | 入金確認済み、出荷待ち |
| 状態 | S3 | 発送済 | 配送業者へ引き渡し済み |
| 状態 | S4 | 完了 | 受取確認済み(終了状態) |
| 状態 | S5 | キャンセル | 注文取消済み(終了状態) |
| イベント | E1 | 入金 | 決済代行から入金通知を受信 |
| イベント | E2 | 出荷 | 倉庫での出荷処理が完了 |
| イベント | E3 | 受取確認 | 配送完了の連携またはユーザー操作 |
| イベント | E4 | キャンセル要求 | ユーザーまたは管理者による取消操作 |
ステップA:状態遷移図を書く
[初期状態]
↓
┌──────────┐ E1:入金 ┌──────────┐ E2:出荷 ┌──────────┐
│ S1 未払い │ ────────→ │ S2 支払済 │ ────────→ │ S3 発送済 │
└──────────┘ └──────────┘ └──────────┘
│ │ │
│ E4:キャンセル要求 │ E4:キャンセル要求 │ E3:受取確認
│ │ ↓
│ │ ┌──────────┐
│ │ │ S4 完了 │◎終了
│ │ └──────────┘
↓ ↓
┌────────────────────────────┐
│ S5 キャンセル │◎終了
└────────────────────────────┘
※ S3 発送済 に対する E4:キャンセル要求 は無効遷移(返品フローで別途対応)この図から読み取れる有効な遷移は、次の5本です。
- T1:S1 未払い + E1 入金 → S2 支払済
- T2:S1 未払い + E4 キャンセル要求 → S5 キャンセル
- T3:S2 支払済 + E2 出荷 → S3 発送済
- T4:S2 支払済 + E4 キャンセル要求 → S5 キャンセル(返金処理を伴う)
- T5:S3 発送済 + E3 受取確認 → S4 完了
ステップB:状態遷移表を作って抜けを洗い出す
状態5×イベント4=20セルの表を作ります。有効な遷移は5本なので、残る15セルをすべて分類する必要があります。
| 状態\イベント | E1 入金 | E2 出荷 | E3 受取確認 | E4 キャンセル要求 |
|---|---|---|---|---|
| S1 未払い | S2 支払済(T1) | ✕ 無効 | ✕ 無効 | S5 キャンセル(T2) |
| S2 支払済 | - 無視(二重入金は返金対象) | S3 発送済(T3) | ✕ 無効 | S5 キャンセル(T4) |
| S3 発送済 | - 無視 | - 無視(再出荷は不可) | S4 完了(T5) | ✕ 無効(返品フローへ) |
| S4 完了 | ✕ 無効 | ✕ 無効 | - 無視 | ✕ 無効(返品フローへ) |
| S5 キャンセル | ✕ 無効 | ✕ 無効 | ✕ 無効 | - 無視 |
表を作ってはじめて見えてくるものがあります。たとえば「S2 支払済 に E1 入金 が再度来たらどうするか」です。
決済代行からの通知が重複して届くことは、実際に起こります。状態遷移図には矢印がないため、図だけを見ていると誰も気づきません。表にしてセルを埋めようとした瞬間に「これ、仕様どうなってましたっけ?」という会話が発生します。
「S5 キャンセル に E1 入金 が来たら」も同じです。ユーザーがキャンセル操作をした直後に、コンビニ払込みをしてしまった場合です。表を作らなければ検討されないまま本番に出ていく典型例です。
状態遷移表は、仕様の抜けを「発見」するのではなく「必ず目に入る場所に露出させる」道具だと考えるとわかりやすいでしょう。
ステップC:0スイッチカバレッジのテストケース一覧
有効な遷移が5本なので、0スイッチカバレッジのテストケースは5件になります。
| No. | 遷移 | 事前状態 | 操作(イベント) | 期待する状態 | 期待する副作用 |
|---|---|---|---|---|---|
| TC-01 | T1 | S1 未払い | 入金通知を受信する | S2 支払済 | 入金確認メール送信、在庫引当が確定する |
| TC-02 | T2 | S1 未払い | キャンセル要求を行う | S5 キャンセル | 在庫引当が解放される、返金処理は発生しない |
| TC-03 | T3 | S2 支払済 | 出荷処理を完了する | S3 発送済 | 発送通知メール送信、追跡番号が登録される |
| TC-04 | T4 | S2 支払済 | キャンセル要求を行う | S5 キャンセル | 返金処理が実行される、在庫引当が解放される |
| TC-05 | T5 | S3 発送済 | 受取確認を行う | S4 完了 | ポイント付与、レビュー依頼メール送信 |
ここで重要なのは、期待結果を「状態」だけでなく「副作用(アクション)」まで書くことです。ステータスは正しく変わったのに返金処理が走っていない、というバグは頻出します。状態遷移図のアクションを、そのまま期待結果の列に落とし込んでください。
ステップD:1スイッチカバレッジのテストケース一覧
1スイッチでは、連続する2つの遷移のペアを網羅します。今回の例では、遷移先が終了状態(S4・S5)になるものには後続がないため、成立するペアは3件です。
| No. | 遷移ペア | 操作シーケンス | 最終状態 | このケースで狙うバグ |
|---|---|---|---|---|
| TC-06 | T1 → T3 | 入金 → 出荷 | S3 発送済 | 入金経由で支払済になった注文が出荷できない |
| TC-07 | T1 → T4 | 入金 → キャンセル要求 | S5 キャンセル | 入金済みなのに返金処理が実行されない |
| TC-08 | T3 → T5 | 出荷 → 受取確認 | S4 完了 | 追跡番号未登録のまま完了になる/ポイント二重付与 |
TC-07が典型例です。0スイッチのTC-04でも「S2 支払済の注文をキャンセルする」ことは確認します。ただしDBを直接書き換えて支払済状態を作った場合、返金に必要な決済IDが登録されていません。
これでは返金処理の不具合を見逃す可能性があります。1スイッチでは初期状態から実際の遷移を辿って到達するため、こうした「到達経路に依存するバグ」を捕まえられます。
ステップE:無効遷移のテストケース一覧
状態遷移表で「✕」を付けたセルのうち、リスクの高いものをテストケース化します。全12件の✕すべてを実施するのが理想ですが、優先度をつけるなら「実行されてしまったときの被害が大きいもの」から選びます。
| No. | 事前状態 | 発生させるイベント | 実行手段 | 期待結果 | 優先度 |
|---|---|---|---|---|---|
| TC-09 | S5 キャンセル | E2 出荷 | 倉庫側APIを直接呼び出す | 状態はS5のまま。エラーを返し、出荷指示が作成されない | 最高 |
| TC-10 | S1 未払い | E2 出荷 | 管理画面のURLを直接入力する | 状態はS1のまま。「入金が確認できません」等のエラー | 最高 |
| TC-11 | S3 発送済 | E4 キャンセル要求 | マイページのキャンセルAPIを直接呼び出す | 状態はS3のまま。返金処理が実行されない | 高 |
| TC-12 | S4 完了 | E4 キャンセル要求 | ブラウザの戻るボタンで再送信する | 状態はS4のまま。ポイントが減算されない | 高 |
| TC-13 | S5 キャンセル | E1 入金 | 決済代行からの入金通知を再送する | 状態はS5のまま。返金対象として記録される | 中 |
| TC-14 | S2 支払済 | E1 入金(重複) | 入金通知を2回送信する | 状態はS2のまま。二重計上されず、重複入金として検知される | 中 |
この表を見ると、無効遷移テストの実行手段が画面操作ではなくAPI直接呼び出しやURL直打ちに寄っていることがわかります。無効遷移テストは、UI操作だけでは実施できないケースが多いのが特徴です。テスト設計の段階で「どうやってその無効な操作を発生させるか」まで決めておかないと、実行フェーズで「押せないので確認不能」となり、テストが形骸化してしまいます。
状態遷移テストが有効なシステム/向かないシステム
状態遷移テストは万能ではありません。適用すべき対象を見極めることが、投下工数に対する効果を最大化します。
| 判定 | システム・機能の特徴 | 具体例 |
|---|---|---|
| 非常に有効 | 状態がDBに保持され、状態によって実行可能な操作が変わる | 注文管理、申請承認ワークフロー、契約ステータス管理 |
| 非常に有効 | モード切替があり、同じ操作でも結果が変わる | 動画プレイヤー、POSレジ、組み込み機器の動作モード |
| 有効 | 認証・権限の状態遷移がある | ログイン/ロック/パスワードリセット、多要素認証 |
| 有効 | 通信の接続状態を管理する | TCP接続、WebSocket、決済端末との通信 |
| 効果が限定的 | 入力値の妥当性検証が主で、状態を持たない | 検索フォーム、計算ツール、入力バリデーション |
| 効果が限定的 | 状態は持つが遷移が一方向で分岐がない | 単純な1画面完結の登録フォーム |
| 向かない | 状態数が膨大で、組み合わせが爆発する | 多数のフラグの組み合わせで振る舞いが決まる機能 |
最後の「状態数が膨大なケース」については補足が必要です。状態が数十〜数百に及ぶ場合、状態遷移表はセル数が数千に達して実用に耐えません。この場合は次のいずれかを検討します。
- 機能単位・サブシステム単位に図を分割する:注文全体ではなく「決済まわりの状態」「配送まわりの状態」に分けて別々の図にする
- 合成状態で階層化する:関連する状態をひとつのまとまりとして扱い、上位レベルの遷移だけをまず整理する
- 条件の組み合わせはデシジョンテーブルへ切り出す:状態ではなく条件フラグの組み合わせで決まる部分は、状態遷移図から分離する
状態遷移テストを実務で回すときの注意点
事前状態の作り方を設計時に決めておく
状態遷移テストは「特定の状態にしてから操作する」ため、事前状態の準備コストが高くなりがちです。DBを直接書き換えて状態を作る方法は手軽ですが、前述のとおり到達経路に依存するバグを見逃すリスクがあります。0スイッチでは準備の簡略化を許容し、1スイッチでは必ず実際の遷移を辿る、といったルールを設計段階で決めておきましょう。
状態遷移図を「テストの成果物」として維持する
状態遷移図は一度書いて終わりではありません。仕様変更で状態やイベントが増えたとき、図と表を更新しないままだと、追加された遷移がテスト対象から漏れます。状態遷移表は回帰テストのスコープ判断にもそのまま使えるため、テスト資産として継続的にメンテナンスする価値があります。
他の技法と組み合わせる
状態遷移テストは「順序」を担当する技法であり、各遷移における入力値の妥当性までは見ません。たとえば「入金額が請求額ちょうどのとき/1円足りないとき」といった観点は境界値分析の領域です。状態遷移テストで骨格を作り、各遷移の入力値を境界値分析で肉付けするという組み合わせが、実務では最も効果的です。
よくある質問(FAQ)
Q. 状態遷移図と状態遷移表は、どちらから作るべきですか?
A. 図から作ることをおすすめします。図は全体の流れを直感的に把握でき、関係者との仕様合意に向いているためです。
図で合意した後に表を作ると、「図には描かれていなかった組み合わせ」が浮かび上がります。仕様の抜けを効率よく発見できます。状態数が少ない場合は、表から作って図に起こす順序でも問題ありません。
Q. 0スイッチカバレッジだけでは不十分ですか?
A. 対象によります。状態変化が業務や金銭に直結しない機能であれば、0スイッチと無効遷移テストで十分なことが多いです。
決済・在庫・権限といった領域では、到達経路によって内部データが異なるケースがあります。1スイッチまで引き上げる価値があります。全機能を一律に1スイッチにするのではなく、リスクベースで適用範囲を決めてください。
Q. 無効遷移のテストは、全部の「✕」セルを実施すべきですか?
A. 理想は全件ですが、優先度をつけるのが現実的です。判断基準は「もし遷移してしまったら、どれだけの被害が出るか」です。
キャンセル済み注文の出荷(実損が発生する)や、ロック済みアカウントでのログイン成功(セキュリティ事故)は最優先です。状態が変わっても実害がない組み合わせは、優先度を下げて構いません。
Q. 状態遷移テストは自動化できますか?
A. 自動化との相性は良好です。状態遷移表という構造化されたデータからテストケースを機械的に導出できるため、データ駆動テストとして実装しやすい特徴があります。特に無効遷移テストはAPIレベルでの確認が中心になるため、UIを介さない自動テストとして組みやすく、回帰テストに組み込む価値が高い領域です。
Q. 状態遷移図に描く「状態」の粒度に迷います。
A. 「その2つを別の状態として区別しないと、同じイベントに対する振る舞いの違いを説明できないか」を基準にしてください。説明できないなら分けるべき状態、説明できるなら1つにまとめてよい状態です。
DBのステータスカラムが取りうる値を、まず候補として全部並べてみてください。議論の出発点になります。
Q. UMLの記法に厳密に従う必要はありますか?
A. テスト設計を目的とする限り、厳密さより「関係者が誤解なく読めること」を優先すべきです。
基本部分はUMLに合わせておくと、開発者との認識齟齬が減ります。初期状態と終了状態の表記、遷移ラベルの書式(イベント[ガード]/アクション)などです。
状態遷移が複雑なシステムのテスト設計は『テスター10』にご相談ください
ここまで見てきたとおり、状態遷移テストは「状態遷移図を書く」だけでは完結しません。状態遷移表で仕様の抜けを洗い出します。0スイッチ/1スイッチのどこまでを網羅するかを、リスクに応じて判断します。
無効遷移をAPIレベルでどう発生させるかまで設計して、はじめて実効性のあるテストになります。この一連の作業には、テスト技法の知識と対象システムの業務理解の両方が必要です。
ソフトウェアテスト代行サービス『テスター10(テスターテン)』では、次のような支援を行っています。
- 状態遷移図・状態遷移表の作成代行:既存の仕様書やソースコード、実際の画面をもとに状態とイベントを洗い出し、未定義の遷移を仕様確認事項としてリストアップします
- カバレッジ基準の設計:機能ごとのリスクを評価し、0スイッチ/1スイッチ/無効遷移テストの適用範囲を工数とのバランスで設計します
- テストケース作成と実行:事前状態の準備手順まで含めた実行可能なテストケースを作成し、実行・不具合報告まで一貫して対応します
- 無効遷移テストのAPI検証:画面上では発生させられない無効遷移を、API直接呼び出しなどの手段で検証します
「注文ステータスまわりで想定外の不具合が繰り返し出ている」「仕様書に状態遷移の記述がなく、どこまでテストすればよいか判断できない」。こうしたお悩みがありましたら、『テスター10』のサービスページより、お気軽にご相談ください。
まとめ
本記事の要点を整理します。
- 状態遷移図は、状態・イベント・遷移・アクション・ガード条件・初期/終了状態の6要素で構成され、UMLではステートマシン図として標準化されている
- 書き方は4ステップ:状態の洗い出し → イベントの洗い出し → 遷移の定義 → 作図。洗い出しと作図を分けることが破綻を防ぐ
- 状態遷移表は行=状態、列=イベント、セル=遷移先。図では見えない「起こりえない遷移」「未定義の遷移」を必ず目に入る場所に露出させる
- 状態遷移テストは操作の順序・履歴に起因するバグを狙う技法で、境界値分析やペアワイズ法とは補完関係にある
- 0スイッチは全遷移を1回ずつ、1スイッチは連続する2遷移の組み合わせを網羅。全体は0スイッチ、リスクの高い領域だけ1スイッチというメリハリが現実的
- 無効遷移のテストは実務で最も被害の大きいバグを防ぐ。画面上で押せなくても、API直接呼び出しやURL直打ちで発生しうる点に注意する
状態遷移図を書くこと自体が目的化してしまうと、労力に見合った効果は得られません。図で全体像を合意し、表で抜けを見つけ、Nスイッチカバレッジでテストの深さを決める。この流れを通しで実行すれば、状態に起因する不具合は効率よく減らせます。
まずは自社の中で「ステータスを持つ機能」をひとつ選び、状態遷移表を作ってみるところから始めてみてください。
次に読むならこの記事
テストの手戻りを減らしたい方へ
テスト仕様書のExcelテンプレートを無料で配布しています。自社で整備する場合も、外部に任せる場合も、まずは型を持つところから。


