初めまして。テストエンジニアリング部のこまです。今回はテスト技法の1つ、「状態遷移」についてのお話です。実際の業務でお世話になることも多い技法であることに加えて、JSTQBの学習を進めている方で苦手意識がある方もいらっしゃるかと思い(私がそうでした)、理解の手助けになればとブログを執筆いたしました。この記事が業務や学習の参考になれば幸いです。
1.状態遷移テストとは?
まずは、状態遷移テストについて説明します。
シラバスにおいて
状態遷移テストについて、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.実際に作ってみる
では、具体的に状態遷移図、状態遷移表の作成をしてみたいと思います。状態遷移図から作成していきます。
状態遷移図を作る
予約のシステム(美容院やお医者さんなど)を例にして考えていきましょう。まずは具体的な仕様を考えてみたいと思います。
※なるだけ簡潔に考えます
– 画面は「予約受付」「会員登録」「日付入力」「利用者情報入力」「予約確認」「予約完了」がある
– 「予約受付」には、「会員」「非会員」のボタンがあり、「会員」は「日付入力」に、「非会員」は「会員登録」へ遷移する
– 「会員登録」は「決定」ボタンで「日付入力」へ、「戻る」で「予約受付」へ遷移する
– 「日付入力」は「決定」ボタンで「利用者情報入力」へ、「戻る」で「予約受付」へ遷移する
– 「利用者情報入力」は「決定」ボタンで「予約確認」へ、「戻る」で「日付入力」へ遷移する
– 「予約確認」は「決定」ボタンで「予約完了」へ、「戻る」で「利用者情報入力」へ遷移する
– 「予約完了」の「閉じる」で予約のフローを終了する
細かく考えようとすると他にもいろいろありそうですが、状態遷移図を考える例としては十分なため、以上の仕様で状態の遷移を考えていきます。状態遷移図を作る手順としては、大まかに「1:状態を配置する」、「2:状態間をイベントで繋ぐ」となります。仕様に記載の画面名が状態に相当し、ボタンがイベントに相当します。(厳密にはイベントはボタンではなくボタン押下時の処理であり、他にもイベントはブラウザバックなど色々あるのですが、個々のイベントが正しく機能するかという確認は別で行った方が効率が良いです。ここではボタン押下のみをイベントとします)
各画面を配置し、間をボタン名で繋いでいくと以下のような図になります。
「予約受付」の前と「受付完了」の後ろに黒丸がありますが、これはそれぞれStartとEndを意味しています。今回は予約システムの遷移のテストのため、その前後は黒丸で省略という意味です。このように、システムを状態遷移図に書き起こすと視覚的にシステムの動きを理解でき、テスト設計時に考慮漏れを防ぐことができます。
状態遷移表を作る
続いて状態遷移表を作ってみましょう。先ほどは「図」でしたが、今度は「表」です。状態を列に入力(イベント)を行に入れると……作成した表は以下の通りです。
「会員」ボタンを押す | 「非会員」ボタンを押す | 「決定」ボタンを押す | 「戻る」ボタンを押す | 「閉じる」ボタンを押す | |
予約受付 | 日付入力 | 会員登録 | – | – | – |
会員登録 | – | – | 日付入力 | 予約受付 | – |
日付入力 | – | – | 利用者情報入力 | 予約受付 | – |
利用者情報入力 | – | – | 予約確認 | 日付入力 | – |
予約確認 | – | – | 予約完了 | 利用者情報入力 | – |
予約完了 | – | – | – | – | End |
End | – | – | – | – | – |
状態と入力(イベント)を総当たりで考えますが、あり得ない状況も出てきます。例えば「予約完了」で「会員」ボタンを押そうとしても押せませんよね。こういうときは「-(ハイフン)」を入れておきます。N/A(not applicable:該当なし)という書き方もあります。いずれにせよ、仕様上あるいは構造上不可能であることを示しています。このように表で表すことで、起こりうる遷移の抜けを防ぎ、あり得ない遷移のテストケースを作成してしまうといった失敗を防ぐことができます。
別の状態遷移表
先ほどお見せした状態遷移表は状態×イベントの状態遷移表となっており、状態とイベントの交差する箇所に遷移後の状態を記載します。これとは別に状態×状態の状態遷移表というものもあります。
予約受付 | 会員登録 | 日付入力 | 利用者情報入力 | 予約確認 | 予約完了 | End | |
予約受付 | – | 「非会員」ボタンを押す | 「会員」ボタンを押す | – | – | – | – |
会員登録 | 「戻る」ボタンを押す | – | 「決定」ボタンを押す | – | – | – | – |
日付入力 | 「戻る」ボタンを押す | – | – | 「決定」ボタンを押す | – | – | – |
利用者情報入力 | – | – | 「戻る」ボタンを押す | – | 「決定」ボタンを押す | – | – |
予約確認 | – | – | – | 「戻る」ボタンを押す | – | 「決定」ボタンを押す | – |
予約完了 | – | – | – | – | – | – | 「閉じる」ボタンを押す |
End | – | – | – | – | – | – | – |
こちらの表では遷移前と遷移後の状態の交差する箇所に発生するイベントを記載します。どちらかというと状態×イベントの表が一般的かと思いますが、どちらも意味するところは同じのため、整理のしやすさ、説明のしやすさで選んでも問題ないです。
状態遷移図、状態遷移表を使用するメリットと気を付けるべきデメリット
ここまでで状態遷移図と状態遷移表の説明を行いましたが、それらを使用することで得られるメリットとデメリットに関して少しお話したいと思います。多少の主観を含みますが、状態遷移図と状態遷移表のメリット、デメリットは以下のようになります。
– それぞれのメリットとデメリットについて
メリット | デメリット | |
状態遷移図 | ・直感的に仕様を理解しやすい | ・仕様変更時の図の更新に手間がかかる ・規模が大きいと作成時の難易度が高まる |
状態遷移表 | ・抜け漏れが発生しにくい ・更新が状態遷移図に比べて容易 ・規模が大きくても作成時の難易度は大きく変わらない |
・直感的な理解は難しい |
特にメリットの1つ目に着目すると、図はインプットで表はアウトプットの足掛かりとして有効であることが分かります。また、両方を使用することで互いのデメリットを補完することができるため、基本的には両方を作成しながら設計を進めることをお勧めします。まずは仕様を整理しながら図を作成し、漏れが無いように表でまとめるという手順で進めると、初めて目にする仕様でも効率よく設計ができると思います。本ブログの解説でも先に状態遷移図を作成し、次に状態遷移表を作成するという流れを取っているので、実際の業務を想像しながら読んでいただくとよりイメージしやすいかもしれません。
4.テスト条件を識別する
状態遷移図と表が完成したところで、いよいよテスト条件を導いていきます。基本的には状態遷移表を確認しつつ、状態(事前)⇒イベント⇒状態(事後)の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スイッチであるべき、とは言えません。機能の重要度、想定される欠陥や、欠陥が与える影響のインパクトなどを考慮して検討する必要があります。
5.ドキュメントのレビューにも役立つ状態遷移の考え方
状態遷移テストの解説そのものは以上となりますが、プラスアルファとして「状態遷移テストの考え方が、動的テスト以外でも役に立つ」というお話をさせてください。私がこれまでテストに従事していた中で、思い返すと状態遷移テストの考えが役に立っているなと感じることがいくつかありました。まずは、ドキュメントを精査する時に、仕様の不備を見つけられるという点です。参画しているプロジェクトにもよりますが、テスト管理者や設計者が要件定義(もしくは基本設計)時点でのドキュメントのレビューをすることもあります。そういったときに状態遷移の考えが役に立ちます。
状態遷移テストの考え方を身に着けていると、見落とされがちな遷移や、特殊な前提の考慮漏れなどといった仕様レベルの欠陥を早期に検知できることがあります。他にも、問合せや市場で欠陥が見つかる等で早期対応の必要が生じた際に、QA側もただ修正版を待つだけでなく、その間に状態遷移表でユーザーステータスと遷移先の振り分けを整理して開発側に提供してサポートをするなど、テスト以外にも役に立つ状況は多々ありました。
まとめ
状態遷移テストについての解説は以上になります。以降は補足となりますが、状態遷移テストに限った話ではなく、テスト技法は「使える」と感じることができるかどうかが重要だと考えています。技法を用いずに気合で全てのテスト条件を探すことも仕様によっては可能ですが、そういった力技に”慣れて”しまうと難解な仕様でも強引に設計してしまい、結果漏れが生まれる可能性が高まってしまいます。
今回の予約システムのように簡単な仕様であれば技法を用いずとも漏れがないテストケースを作成することはさほど難しくありませんが、簡単な仕様でも使える時は使っていくことを繰り返すと難解な仕様にもすぐに適用できるのではと思っています。状態遷移に苦手意識を感じている方は、まずは例のシステムと同等か、もっと簡単な仕様で状態遷移に慣れる事から初めてみてください。補足を含め、以上が状態遷移テストについての解説となります。状態遷移テストについての概要、状態遷移図や状態遷移表の作り方について、理解の助けになれたのであれば幸いです。