初めまして。テストエンジニアリング部のこまです。
今回はテスト技法の1つ、「状態遷移」についてのお話です。実際の業務でお世話になることも多い技法であることに加えて、JSTQBの学習を進めている方で苦手意識がある方もいらっしゃるかと思い(私がそうでした)、理解の手助けになればとブログを執筆いたしました。この記事が業務や学習の参考になれば幸いです。
1. 状態遷移テストの基本概念
まずは、状態遷移テストについて説明します。
JSTQBシラバスにおける状態遷移テストの定義
状態遷移テストについて、JSTQB FLレベルでは以下のように記載されています。
コンポーネントやシステムは、現在の条件や過去の履歴(システムの初期化後から起きるイベントなど)によって、イベントに対して異なる振る舞いをする。過去の履歴は、状態の概念を使用してまとめることができる。状態遷移図は、ソフトウェアの取り得る状態、ソフトウェアが開始および終了する方法、ソフトウェアが状態間で遷移する方法を示す。遷移はイベントにより開始される(例えば、ユーザ ーによるフィールドへの値入力)。イベントは遷移を引き起こす。同じイベントが同じ状態から複数の異なる遷移を引き起こすこともある。状態が変化するとソフトウェアでアクションが実行される(計算結果またはエラーメッセージの表示など)。
少々難解ですが、まとめると「ソフトウェアの状態やイベントによってどの様に振舞うかは状態遷移図などでまとめることができますよ」ということです。
状態遷移テストの簡単な例
シラバスの記述を引用しましたが、これだけではどの様なテストかのイメージが難しいかと思いますので、簡単な例を紹介します。イベントaで状態AからBへ遷移、イベントbで状態BからCへ遷移、というシステムを想定します。これらの状態やイベントを状態遷移図と状態遷移表を用いて遷移や状態のパターンをまとめ、漏れなく確認します。以下に状態遷移図と状態遷移表の簡単なサンプルを示します。以降の章でさらに深堀りしたいと思いますので、ここではイメージをつかむため極限までシンプルなものとさせていただきます。
簡単な画面遷移図の例

簡単な画面遷移表の例
| イベントa | イベントb | |
| 状態A | 状態B | – |
| 状態B | – | 状態C |
| 状態C | – | – |
このように、仕様を図や表で表し、確認すべき内容を明確にします。今例にしているシステムでは、「状態Aのとき、イベントaが発生した際にちゃんと状態Bへ遷移するか」といったところを確認することが状態遷移テストです。
【状態遷移テスト基本用語集】
- 状態:システムやコンポーネントが特定の時点で持つ条件や性質
- イベント:状態の変化を引き起こすきっかけとなる入力や条件
- 遷移:ある状態から別の状態への変化
- アクション:遷移時に実行される処理や振る舞い
- 初期状態:システムの開始時点での状態
- 終了状態:システムの処理完了時の状態
2. 状態遷移テストが効果的なシナリオ
今度は、JSTQB Advanced TAの記載を参照しますが、シラバスでは
状態遷移テストは、定義済みの状態を持ち、それらの状態間の遷移(例えば、画面の変更) を引き起こすイベントを持つすべてのソフトウェアに適用できる。
とあります。つまり、「状態」と「イベント」の2種類の要素をもつソフトウェアで使用可能という事です。ほぼ全てのソフトウェアで使用可能かと思いますが、実務において特に有効と感じるのは以下のような機能がスコープに含まれる時です。
- 画面遷移
- ステータスの更新を行う処理(登録、購入、支払等)
一方で、パラメータの反映やUIのテストなど、イベントや遷移が無いものに対しては他のテスト技法の方が適している場合が多いです。また、シラバスにおいて、状態遷移テストは「すべてのテストレベル で使用できる」と記載されています。コンポーネントテストから受入テストまでのどんなテストレベルでも使用できるという事なので、担当しているテストレベルによっては使えない、という事はありません。
状態遷移テスト適用の判断基準
状態遷移テストが特に効果的なシステムの特徴
- 明確な状態を持つシステム
- ステータス管理機能、ワークフロー管理、オンライン予約など
- トリガーイベントで状態が変化するシステム
- 注文処理、承認フロー、ステータス更新機能など
- 状態に応じて振る舞いが変わるシステム
- ユーザー権限による表示/非表示、状態依存の機能制限など
- ユーザーインタラクションが多いシステム
- フォーム入力、ウィザード形式の処理など これらの特徴を持つシステムでは、状態遷移テストを適用することで、想定外の状態やイベントの組み合わせによる不具合を効率的に検出できます。
3. 状態遷移図と状態遷移表の作成方法
では、具体的に状態遷移図、状態遷移表の作成をしてみたいと思います。状態遷移図から作成していきます。
状態遷移図とは
状態遷移図とは、システムやオブジェクトが持つ各状態と、状態間の変化(遷移)を視覚的に表現した図です。円や四角で状態を表し、矢印で遷移を示します。遷移の条件やトリガーとなるイベントも記載されることが多く、ソフトウェア設計やシステム分析において、動的な振る舞いを理解しやすくするために使用されます。UMLの一種としても広く活用されています。
状態遷移図の具体的な作成例
予約のシステム(美容院やお医者さんなど)を例にして考えていきましょう。まずは具体的な仕様を考えてみたいと思います。
※なるべく簡潔に考えます
- 画面は「予約受付」「会員登録」「日付入力」「利用者情報入力」「予約確認」「予約完了」がある
- 「予約受付」には、「会員」「非会員」のボタンがあり、「会員」は「日付入力」に、「非会員」は「会員登録」へ遷移する
- 「会員登録」は「決定」ボタンで「日付入力」へ、「戻る」で「予約受付」へ遷移する
- 「日付入力」は「決定」ボタンで「利用者情報入力」へ、「戻る」で「予約受付」へ遷移する
- 「利用者情報入力」は「決定」ボタンで「予約確認」へ、「戻る」で「日付入力」へ遷移する
- 「予約確認」は「決定」ボタンで「予約完了」へ、「戻る」で「利用者情報入力」へ遷移する
- 「予約完了」の「閉じる」で予約のフローを終了する
細かく考えようとすると他にもいろいろありそうですが、状態遷移図を考える例としては十分なため、以上の仕様で状態の遷移を考えていきます。状態遷移図を作る手順としては、大まかに「1:状態を配置する」、「2:状態間をイベントで繋ぐ」となります。仕様に記載の画面名が状態に相当し、ボタンがイベントに相当します。(厳密にはイベントはボタンではなくボタン押下時の処理であり、他にもイベントはブラウザバックなど色々あるのですが、個々のイベントが正しく機能するかという確認は別で行った方が効率が良いです。ここではボタン押下のみをイベントとします)
各画面を配置し、間をボタン名で繋いでいくと以下のような図になります。

「予約受付」の前と「受付完了」の後ろに黒丸がありますが、これはそれぞれStartとEndを意味しています。今回は予約システムの遷移のテストのため、その前後は黒丸で省略という意味です。このように、システムを状態遷移図に書き起こすと視覚的にシステムの動きを理解でき、テスト設計時に考慮漏れを防ぐことができます。
状態遷移表とは
状態遷移表とは、システムの現在の状態と入力イベントに対して、次の状態と出力動作を表形式で整理したものです。行に現在状態、列に入力条件を配置し、交差する箇所に次状態や出力を記述します。状態遷移図と同じ情報を含みますが、表形式のため網羅性の確認や実装時の参照が容易で、プログラミングや論理設計において状態機械の仕様を明確に定義する際によく使用されます。
状態遷移表の作成例と種類
続いて状態遷移表を作ってみましょう。先ほどは「図」でしたが、今度は「表」です。状態を列に入力(イベント)を行に入れると……作成した表は以下の通りです。
| 「会員」ボタンを押す | 「非会員」ボタンを押す | 「決定」ボタンを押す | 「戻る」ボタンを押す | 「閉じる」ボタンを押す | |
| 予約受付 | 日付入力 | 会員登録 | – | – | – |
| 会員登録 | – | – | 日付入力 | 予約受付 | – |
| 日付入力 | – | – | 利用者情報入力 | 予約受付 | – |
| 利用者情報入力 | – | – | 予約確認 | 日付入力 | – |
| 予約確認 | – | – | 予約完了 | 利用者情報入力 | – |
| 予約完了 | – | – | – | – | End |
| End | – | – | – | – | – |
状態と入力(イベント)を総当たりで考えますが、あり得ない状況も出てきます。例えば「予約完了」で「会員」ボタンを押そうとしても押せませんよね。こういうときは「-(ハイフン)」を入れておきます。N/A(not applicable:該当なし)という書き方もあります。いずれにせよ、仕様上あるいは構造上不可能であることを示しています。このように表で表すことで、起こりうる遷移の抜けを防ぎ、あり得ない遷移のテストケースを作成してしまうといった失敗を防ぐことができます。
別の状態遷移表
先ほどお見せした状態遷移表は状態×イベントの状態遷移表となっており、状態とイベントの交差する箇所に遷移後の状態を記載します。これとは別に状態×状態の状態遷移表というものもあります。
| 予約受付 | 会員登録 | 日付入力 | 利用者情報入力 | 予約確認 | 予約完了 | End | |
| 予約受付 | – | 「非会員」ボタンを押す | 「会員」ボタンを押す | – | – | – | – |
| 会員登録 | 「戻る」ボタンを押す | – | 「決定」ボタンを押す | – | – | – | – |
| 日付入力 | 「戻る」ボタンを押す | – | – | 「決定」ボタンを押す | – | – | – |
| 利用者情報入力 | – | – | 「戻る」ボタンを押す | – | 「決定」ボタンを押す | – | – |
| 予約確認 | – | – | – | 「戻る」ボタンを押す | – | 「決定」ボタンを押す | – |
| 予約完了 | – | – | – | – | – | – | 「閉じる」ボタンを押す |
| End | – | – | – | – | – | – | – |
こちらの表では遷移前と遷移後の状態の交差する箇所に発生するイベントを記載します。どちらかというと状態×イベントの表が一般的かと思いますが、どちらも意味するところは同じのため、整理のしやすさ、説明のしやすさで選んでも問題ないです。
状態遷移図と状態遷移表のメリット・デメリット比較
ここまでで状態遷移図と状態遷移表の説明を行いましたが、それらを使用することで得られるメリットとデメリットに関して少しお話したいと思います。多少の主観を含みますが、状態遷移図と状態遷移表のメリット、デメリットは以下のようになります。
それぞれのメリットとデメリットについて
| メリット | デメリット | |
| 状態遷移図 | ・直感的に仕様を理解しやすい | ・仕様変更時の図の更新に手間がかかる ・規模が大きいと作成時の難易度が高まる |
| 状態遷移表 | ・抜け漏れが発生しにくい ・更新が状態遷移図に比べて容易 ・規模が大きくても作成時の難易度は大きく変わらない |
・直感的な理解は難しい |
特にメリットの1つ目に着目すると、図はインプットで表はアウトプットの足掛かりとして有効であることが分かります。また、両方を使用することで互いのデメリットを補完することができるため、基本的には両方を作成しながら設計を進めることをお勧めします。まずは仕様を整理しながら図を作成し、漏れが無いように表でまとめるという手順で進めると、初めて目にする仕様でも効率よく設計ができると思います。本ブログの解説でも先に状態遷移図を作成し、次に状態遷移表を作成するという流れを取っているので、実際の業務を想像しながら読んでいただくとよりイメージしやすいかもしれません。
状態遷移モデリングのベストプラクティス
効果的な状態遷移図・表作成のポイント
- 適切な抽象度の選択:細かすぎると複雑化し、大まかすぎると不具合を見逃す
- 状態の明確な定義:各状態が何を表すかを明確に文書化する
- すべての遷移の網羅:発生しうるすべての状態変化を考慮する
- 例外状態の考慮:エラー状態や例外的な遷移も含める
- ツールの活用:UMLツールや専用のテストモデリングツールを活用する
状態遷移図と状態遷移表は相互補完的です。図は直感的な理解を助け、表は網羅性を確保します。両方を併用することで、より堅牢なテスト設計が可能になります。
4. テスト条件の識別とNスイッチテスト
状態遷移図と表が完成したところで、いよいよテスト条件を導いていきます。基本的には状態遷移表を確認しつつ、状態(事前)⇒イベント⇒状態(事後)の1つの流れを1つのテスト条件として表していきます。実際にテスト条件を導く前に、Nスイッチテスト(Nスイッチカバレッジ)の説明をさせていただきます。
Nスイッチテストの概念と重要性
Nスイッチテストについて簡単に説明すると、N+1回の遷移を行うパターンを1つのテスト条件とする、というものになります。1回の遷移の確認は0+1となるのでN0(0スイッチテスト)と呼ばれます。一般的に使用されるものはN0とN1で、どちらを採用するかはテストの対象やQCDのバランスになります。NスイッチカバレッジはNスイッチテストをどれだけ網羅したかを表す数値となります。つまり、「0スイッチカバレッジ100%」=「0スイッチテストの全パターンを網羅した」という意味になります。これらの事を踏まえて、0スイッチと1スイッチでそれぞれテスト条件を見てみましょう。
0スイッチテストの条件設計
| 状態 | イベント | 状態 | |
| 1 | 予約受付 | 「会員」ボタンを押す | 日付入力 |
| 2 | 予約受付 | 「非会員」ボタンを押す | 会員登録 |
| 3 | 会員登録 | 「決定」ボタンを押す | 日付入力 |
| 4 | 会員登録 | 「戻る」ボタンを押す | 予約受付 |
| 5 | 日付入力 | 「決定」ボタンを押す | 利用者情報入力 |
| 6 | 日付入力 | 「戻る」ボタンを押す | 予約受付 |
| 7 | 利用者情報入力 | 「決定」ボタンを押す | 予約確認 |
| 8 | 利用者情報入力 | 「戻る」ボタンを押す | 日付入力 |
| 9 | 予約確認 | 「決定」ボタンを押す | 予約完了 |
| 10 | 予約確認 | 「戻る」ボタンを押す | 利用者情報入力 |
| 11 | 予約完了 | 「閉じる」ボタンを押す | End |
1スイッチテストの条件設計
| 状態1 | イベント1 | 状態2 | イベント2 | 状態3 | |
| 1 | 予約受付 | 「会員」ボタンを押す | 日付入力 | 「決定」ボタンを押す | 利用者情報入力 |
| 2 | 予約受付 | 「会員」ボタンを押す | 日付入力 | 「戻る」ボタンを押す | 予約受付 |
| 3 | 予約受付 | 「非会員」ボタンを押す | 会員登録 | 「決定」ボタンを押す | 日付入力 |
| 4 | 予約受付 | 「非会員」ボタンを押す | 会員登録 | 「戻る」ボタンを押す | 予約受付 |
| 5 | 会員登録 | 「決定」ボタンを押す | 日付入力 | 「決定」ボタンを押す | 利用者情報入力 |
| 6 | 会員登録 | 「決定」ボタンを押す | 日付入力 | 「戻る」ボタンを押す | 予約受付 |
| 7 | 会員登録 | 「戻る」ボタンを押す | 予約受付 | 「会員」ボタンを押す | 日付入力 |
| 8 | 会員登録 | 「戻る」ボタンを押す | 予約受付 | 「非会員」ボタンを押す | 会員登録 |
| 9 | 日付入力 | 「決定」ボタンを押す | 利用者情報入力 | 「決定」ボタンを押す | 予約確認 |
| 10 | 日付入力 | 「決定」ボタンを押す | 利用者情報入力 | 「戻る」ボタンを押す | 日付入力 |
| 11 | 日付入力 | 「戻る」ボタンを押す | 予約受付 | 「会員」ボタンを押す | 日付入力 |
| 12 | 日付入力 | 「戻る」ボタンを押す | 予約受付 | 「非会員」ボタンを押す | 会員登録 |
| 13 | 利用者情報入力 | 「決定」ボタンを押す | 予約確認 | 「決定」ボタンを押す | 予約完了 |
| 14 | 利用者情報入力 | 「決定」ボタンを押す | 予約確認 | 「戻る」ボタンを押す | 利用者情報入力 |
| 15 | 利用者情報入力 | 「戻る」ボタンを押す | 日付入力 | 「決定」ボタンを押す | 利用者情報入力 |
| 16 | 利用者情報入力 | 「戻る」ボタンを押す | 日付入力 | 「戻る」ボタンを押す | 予約受付 |
| 17 | 予約確認 | 「決定」ボタンを押す | 予約完了 | 「閉じる」ボタンを押す | End |
| 18 | 予約確認 | 「戻る」ボタンを押す | 利用者情報入力 | 「決定」ボタンを押す | 予約確認 |
| 19 | 予約確認 | 「戻る」ボタンを押す | 利用者情報入力 | 「戻る」ボタンを押す | 日付入力 |
| 20 | 予約完了 | 「閉じる」ボタンを押す | End | – | – |
スイッチレベルの選定ガイドライン
比較すると、1スイッチテストの方が広く深く確認できるテスト条件になりました。しかし、数が増えた上に手順も複雑化するため、欠陥を検出する可能性は高まると同時に必要なコストも大きくなります。0スイッチと1スイッチのどちらを採用すべきかという点について、個人的な見解ですが、コスト等を加味し可能であれば1スイッチでテストしたい所です。
というのも、状態遷移テストで検知する欠陥として事後状態、もしくはその後の操作に対するものが多いからです。1回のイベントと事後状態に問題は無いが、特定の遷移法を取ったうえで戻るボタン(1スイッチテストで表すところのイベント2)で欠陥、といった挙動は何度も見てきました。
もちろん、スケジュールをはじめとする他の要因も考慮するため、絶対に1スイッチであるべき、とは言えません。機能の重要度、想定される欠陥や、欠陥が与える影響のインパクトなどを考慮して検討する必要があります。
スイッチカバレッジの選択ガイドライン
適切なNスイッチカバレッジレベルの選択基準
- 0スイッチカバレッジが適する場合
- リソースや時間が限られている
- システムの複雑性が低い
- 基本機能の検証が主目的
- 1スイッチカバレッジが適する場合
- 複雑な状態依存性がある
- ユーザーの操作順序に依存する振る舞いがある
- 過去に状態間の遷移連鎖に関する不具合が検出されている
- 2以上のスイッチカバレッジが適する場合
- 極めて高い品質要求がある(例:安全性が重要なシステム)
- 複雑な状態履歴に依存する振る舞いがある
プロジェクトの制約とリスク評価に基づいて、適切なカバレッジレベルを選択しましょう。
5. ドキュメントレビューへの応用
状態遷移テストの解説そのものは以上となりますが、プラスアルファとして「状態遷移テストの考え方が、動的テスト以外でも役に立つ」というお話をさせてください。
私がこれまでテストに従事していた中で、思い返すと状態遷移テストの考えが役に立っているなと感じることがいくつかありました。まずは、ドキュメントを精査する時に、仕様の不備を見つけられるという点です。参画しているプロジェクトにもよりますが、テスト管理者や設計者が要件定義(もしくは基本設計)時点でのドキュメントのレビューをすることもあります。そういったときに状態遷移の考えが役に立ちます。
状態遷移テストの考え方を身に着けていると、見落とされがちな遷移や、特殊な前提の考慮漏れなどといった仕様レベルの欠陥を早期に検知できることがあります。他にも、問合せや市場で欠陥が見つかる等で早期対応の必要が生じた際に、QA側もただ修正版を待つだけでなく、その間に状態遷移表でユーザーステータスと遷移先の振り分けを整理して開発側に提供してサポートをするなど、テスト以外にも役に立つ状況は多々ありました。
【状態遷移の考え方を活用したレビューチェックリスト】
要件・設計ドキュメントレビュー時の状態遷移視点でのチェックポイント
- すべての状態が明確に定義されているか
- 各状態からの遷移条件と遷移先が明確か
- 初期状態と終了状態が定義されているか
- 例外状態とリカバリー方法が定義されているか
- 状態の循環(無限ループ)のリスクはないか
- すべての状態に対して到達可能性と終了可能性があるか
- 同じイベントが複数の遷移を引き起こす場合、その条件が明確か
これらのチェックポイントを活用することで、開発の早期段階で仕様の不備や矛盾を発見し、手戻りを防ぐことができます。
まとめ
状態遷移テストについての解説は以上になります。
以降は補足となりますが、状態遷移テストに限った話ではなく、テスト技法は「使える」と感じることができるかどうかが重要だと考えています。技法を用いずに気合で全てのテスト条件を探すことも仕様によっては可能ですが、そういった力技に”慣れて”しまうと難解な仕様でも強引に設計してしまい、結果漏れが生まれる可能性が高まってしまいます。
今回の予約システムのように簡単な仕様であれば技法を用いずとも漏れがないテストケースを作成することはさほど難しくありませんが、簡単な仕様でも使える時は使っていくことを繰り返すと難解な仕様にもすぐに適用できるのではと思っています。状態遷移に苦手意識を感じている方は、まずは例のシステムと同等か、もっと簡単な仕様で状態遷移に慣れる事から初めてみてください。補足を含め、以上が状態遷移テストについての解説となります。状態遷移テストについての概要、状態遷移図や状態遷移表の作り方について、理解の助けになれたのであれば幸いです。

