【テスト技法】状態遷移テスト

# はじめに
こんにちは。アメリカで独学でエンジニアを目指している者です。
現在はRailsを勉強しているのですが、並行してソフトウェアテスト技法も学ぶことで、Railsチュートリアルの理解が深まるのではないかと考え、テスト技法の勉強を始めました。
今回学んだ状態遷移テストについて、記憶が薄れないうちに簡単にまとめておきたいと思います。
ちなみに、テスト技法はUdemyで勉強しています。とても分かりやすいので、テスト技法を勉強したいと思う方はぜひ見てみてください。

https://www.udemy.com/share/102NaE3@Klm5Y802jzOOWemmUmgcZKwsmg5ZeKSLdssOdLltCQUeMwrYsLoBehQBwhoefOb3yw==/

# 状態遷移テストとは
状態遷移テストは、システムの入力やイベントに応じた状態の変化（状態遷移）をモデル化し、そのすべての遷移パターンや条件を網羅的にテストする手法です。システムが持つ各状態と、それらの間の遷移ルールを明確に定義することで、予期しない動作や不具合を早期に発見できるメリットがあります。

## 状態遷移図の作成
状態遷移テストは、システムの入力やイベントに応じた状態の変化（状態遷移）をモデル化し、そのすべての遷移パターンや条件を網羅的にテストする手法です。
システムが持つ各状態と、それらの間の遷移ルールを明確に定義することで、予期しない動作や不具合を早期に発見できるメリットがあります。

* 状態（State）: システムが取り得る各種状態。例えば、「ログイン前」、「ログイン後」、「エラー状態」など。
* 遷移（Transition）: ある状態から別の状態へ移行する際の条件やイベント。例えば、「正しい認証情報入力時」、「パスワード入力ミス時」など。
* イベント（Event）: 状態を変化させるトリガーとなる操作や入力データ。


## テスト実施の流れと考慮事項
状態遷移テストを実際に実施する際は、以下の流れでテストケースを整理し、テストを進めていくと効果的です。

1. 状態・イベントの洗い出し
まず、システムの仕様書やユーザーシナリオをもとに、考えられる全ての状態とイベントをリストアップします。今回の例では、オンラインバンキングのログイン処理における「未ログイン」「エラーメッセージ表示」「ログイン成功」「アカウントロック」といった状態、及び「正しいパスワード入力」「誤ったパスワード入力」「ログアウト」といったイベントが該当します。

2. 状態遷移図と状態遷移表の作成
状態間の関係性を視覚化するために状態遷移図を作成し、それに基づいて状態遷移表を整備します。状態遷移表は、テスト実施時にどの組み合わせが適切であるかを確認するための羅針盤となります。

3. テストケースの作成と実装
状態遷移表に沿って、各組み合わせ（状態＋イベント）のテストケースを作成します。該当しない組み合わせ（N/A）の場合は、その動作が行われないこと、またはシステムが適切に例外処理を実施することを確認するテストとなります。

4. テスト実行と結果の評価
実際のシステムでテストケースを実行し、期待通りの状態遷移が行われるかを検証します。もし期待と異なる動作が発生した場合は、仕様の見直しや実装の修正を検討します。

## 具体例
ここでは、オンラインバンキングのログイン処理を具体例として考えます。

* 状態
  * 未ログイン（初期状態）
  * ログイン成功（正しい認証情報が入力された場合）
  * アカウントロック（パスワードを一定回数以上間違えた場合）
  * エラーメッセージ表示（パスワードを誤ったが、ロックされていない場合）
* 遷移ルール
  * 未ログイン から 正しいパスワード を入力すると ログイン成功 へ遷移。
  * 未ログイン から 間違ったパスワード を入力すると エラーメッセージ表示 へ遷移し、試行回数がカウントされる。
  * エラーメッセージ表示 から 再び間違ったパスワード を入力すると エラーメッセージ表示 を繰り返す。
  * 3回連続で間違える と アカウントロック に遷移し、以降ログインできなくなる。

まずは以下のような状態遷移図を書くことができます

```
+---------------+          +----------------+
|  未ログイン   | -------> |  ログイン成功   | (正しいパスワード)
+---------------+          +----------------+
      |                              ↑
      | (誤ったパスワード)            | (ログアウト)
      v                              |
+-------------------+                 |
| エラーメッセージ表示 | -----> (再試行) |
+-------------------+                 |
      |                                |
      | (3回間違えたら)                 |
      v                                |
+------------------+                   |
| アカウントロック  | <----------------+
+------------------+
```
この状態遷移図を踏まえて、状態遷移表も作成します。
| イベント/状態          | ⓪未ログイン状態 | ①エラーメッセージ表示 | ②ログイン成功 | ③アカウントロック | 
| ---------------------- | ---------------- | ---------------------- | -------------- | ------------------ | 
| 正しいパスワードの入力 | ②               | ②                     | N/A            | N/A                | 
| 誤ったパスワードの入力 | ①               | ①                     | N/A            | N/A                | 
| ログアウト             | N/A              | N/A                    | ⓪             | N/A                | 

※「N/A」は、該当する状態に対してそのイベントが適用不可であることを意味します。必要に応じ、該当しない状態に対してもテストを行い、システムが正しく例外処理していることを確認することが望ましいです。

## 状態遷移表を活用したテストケース設計のポイント
上記の状態遷移表では、各状態において実施可能なイベントと、その結果として得られる状態を整理しました。これにより、テスト実施時は以下の点に注意できます。

* 全イベントの検証
各状態で入力可能なイベントが明確になっているため、たとえば未ログイン状態で正しいパスワードを入力した場合に必ずログイン成功状態となることを確認します。

* 不適用なイベントの確認
状態遷移表で「N/A」と記載されている組み合わせでは、そのイベントが実行されない（または意味をなさない）ことを示しています。これにより、意図しない操作に対してシステムがどのように対応するかを確認する重要なテストケースとなります。

* 異常系のチェック
今回は正常系として整理していますが、誤ったパスワード入力が連続して実施された場合の試行回数のカウントやアカウントロックへの遷移など、異常系の動作も検証する必要があります。異常系のテストケースでは、カウントリセットのタイミングやロック後の解除手続きなど、実際の業務要件に合わせた詳細な仕様に基づいてテストを追加します。

## まとめ
今回の記事では、状態遷移テストの基本概念から、オンラインバンキングのログイン処理を具体例として状態遷移図と状態遷移表の作成、さらにテストケース設計の流れについて解説しました。
次回は、Nスイッチカバレッジについての記事を予定しています。