UMLステートマシン図を用いた状態遷移テストの注意点

[ソフトウェアテスト Advent Calendar 2018](https://qiita.com/advent-calendar/2018/softwaretesting) 4日目担当の @ToshiManaPlus1 です。

前日(3日目)は @YoshikiIto さんによる [テストチームにおけるWiki等のナレッジベースでの情報共有のコツ](https://yoshikiito.net/blog/archives/2168) でした。

# はじめに

状態遷移テストでは状態遷移図を用意するのが多いと思います。状態遷移図を記述するツールは多数ありますが、UML準拠のツール[^uml]を使うことが多いのではないでしょうか。また、開発で用いていたUMLのモデルを用いて状態遷移テストを設計をする場合があるかもしれません。
[^uml]: Astah*, Enterprise Architect, PlantUMLなど
しかし、UMLツールでモデルを書いて「状態遷移テストをやろう」となったときに、UMLの記法が原因で上手くテスト設計できない場合があります。
今回はUMLの記法が状態遷移テストに与える影響をいくつか説明したいと思います。

## 前提

本記事では状態遷移図はDFA[^dfa]に基づいているものとします。
[^dfa]: Deterministic finite automaton (決定性有限オートマトン)
UMLにおける状態遷移図相当はステートマシン図と呼ばれています。本記事では、ガードや履歴状態といったUML特有の記法を含むものをステートマシン図、含まないものを状態遷移図として区別します。[^fsm]
[^fsm]: 本記事での定義であり、一般的な定義かどうかは分かりません。

## 背景

一般的に状態遷移テストの説明で用いられるモデルは状態遷移図です。[^proof]
[^proof]: 手元で確認した資料(ソフトウェアテスト技法ドリル(著：秋山浩一)、ソフトウェアテストの教科書(著：石原一宏／田中英和))では、状態遷移テストの説明にUML特有の記法は確認できませんでした。
私の知る限り[^noknowledge]、ステートマシン図での状態遷移テストについて説明した資料は数が少ないです。[^fsm1][^fsm2]
そのため、どのような注意が必要かがあまり議論されていないように思います。
本記事では、ステートマシン図から状態遷移テストを設計する上で注意が必要だと感じた点を整理しています。
[^noknowledge]: 私の理解が足りない可能性があります。
[^fsm1]: https://www.slideshare.net/kjstylepp/wacate2013-29199595?next_slideshow=1
[^fsm2]: :http://astah.change-vision.com/ja/qs/manual/tutorial/basic_state_path.html

# 概要

以下のケースにおける、ステートマシン図から状態遷移テストを設計するときの注意点について説明します。

- ガードを用いたステートマシン図

- (浅い)履歴状態を用いたステートマシン図

# ガードを用いたステートマシン図

題材は某国民的横スクロール型アクションゲーム[^mario]とします。ガードを含んだステートマシン図と等価の状態遷移図を比較します。

[^mario]: スーパー〇リオブラザーズ

## 検討

ガードを含んだステートマシン図から状態遷移図へ変換していく過程を示します。

### ステートマシン図(ガードあり、直交合成状態あり)
ガードを含んだ以下のようなステートマシン図を扱います。ガードを含む遷移を赤字で示します。直交合成状態を含んだ表現は状態遷移図／ステートマシン図の整理を容易にします。しかし直交合成状態を含んだ表現から直接Nカバレッジテストを設計することは困難です。
![アクションゲーム.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/73a07f1c-8189-14b3-9471-665a705eae75.jpeg)

### ステートマシン図(ガードあり、直交合成状態なし)
上記のステートマシン図(ガードあり、直交合成状態あり)では「ゲーム中」が直交合成状態として表現されています。2つの領域を1つの領域に変換すると、以下のようなステートマシン図になります。ガードを含む遷移は「ガード条件を満たす遷移」と「ガード条件を満たさない遷移」を2つを検討する必要があります。そのため、Nカバレッジテストの際は、見た目以上に多くの遷移をテストする必要があります。

![アクションゲーム_中間.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/ad64e649-337b-25da-4af6-23245cb09df4.jpeg)

### 状態遷移図(ガードなし、直交合成状態なし)
上記のステートマシン図(ガードあり、直交合成状態なし)のガード条件が状態に依存しています。そのため、ガードをなくして表現すると以下のような状態遷移図になります。上記のステートマシン図(ガードあり、直交合成状態なし)から遷移先が変わった遷移を青字で示します。

![アクションゲーム_最終.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/e4c9b193-f7d0-3158-bd12-906303e239a5.jpeg)

### 状態遷移図(ガードなし、直交合成状態あり)

状態遷移図(ガードなし)の場合、直交合成状態として領域を分割することができません。

## 検討結果から考えられる注意点

検討から以下のことが注意点として挙げられます。

- ガードを含む遷移は「ガード条件を満たす遷移」と「ガード条件を満たさない遷移」の2つを検討する必要がある。ガードを含む遷移はステートマシンの見かけ上では1つの遷移で表現されているため、Nカバレッジテストを行う際に抜けが発生するかもしれない。

- ガードを含んだステートマシン図だと直交合成状態で表現できて、ガードのない状態遷移図では直交合成状態で表現できない場合がある。直交合成状態は各領域が並行に動作しても正しく機能する(入力に対して期待結果が一位に定まる)ことが期待される。しかし、ステートマシン図での直交合成状態の各領域が並行に動作した場合、正しく機能しない(入力に対して期待結果が一意に定まらない)可能性がある。

||直交合成状態あり|直交合成状態なし|
|:-:|:-:|:-:|
|ステートマシン図(ガードあり)|![アクションゲーム.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/73a07f1c-8189-14b3-9471-665a705eae75.jpeg)|![アクションゲーム_中間.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/ad64e649-337b-25da-4af6-23245cb09df4.jpeg)|
|状態遷移図(ガードなし)|×表現不可|![アクションゲーム_最終.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/e4c9b193-f7d0-3158-bd12-906303e239a5.jpeg)|


# (浅い)履歴状態を用いたステートマシン図

題材は単純化したオーディオプレーヤーとします。履歴状態のなし／ありを比較します。

## 検討

履歴状態のない状態遷移図を検討した後に、履歴状態のあるステートマシン図を検討します。

### 履歴状態なしの状態遷移図

以下のような直交合成状態を含む履歴状態のない状態遷移図を扱います。

![履歴なし.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/67b6895c-9ee6-c074-3971-2c18978b29cb.jpeg)

上記の状態遷移図から、状態の粒度を揃えた状態遷移図を以下に示します。

![履歴なし_合成.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/d629d413-082b-7116-cd2f-0efed3a440c0.jpeg)

### 履歴状態ありのステートマシン図

「再生モード」について、電源断後に電源投入しても前回の再生モードが維持できるように履歴状態を導入します。履歴状態のない状態遷移図(直交合成状態あり)と比較をしても、履歴状態以外は差異がなく、見た目上の影響が小さいことが分かります。

![履歴あり.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/d55f9f3b-52a1-7c48-84e4-3ee4e1055f56.jpeg)

上記ステートマシン図から、状態の粒度を揃えて、かつ履歴状態があるステートマシン図と等価になる状態遷移図を検討した結果を以下に示します。履歴状態を持っていた「電源ON」の状態は履歴状態を持たない状態遷移図(直交合成状態ない)と相違ありません。しかし、履歴状態を持っていない「電源OFF」が「再生モード」の状態を保持するようになりました。

![履歴あり_合成.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/cb3c1d0a-f531-87cd-013a-f1e9cad096ba.jpeg)

## 検討結果から考えられる注意点

検討から以下のことが注意点として挙げられます。

- 履歴状態ありのステートマシン図を履歴状態なしの状態遷移図に変換する場合、履歴状態を持っていなかった状態の数が増える。

- 履歴状態あり／なしがステートマシン図／状態遷移図の見た目に与える影響が小さい場合がある。しかし、状態遷移テストへの影響が小さいとは限らない。

||直交合成状態あり|直交合成状態なし|
|:-:|:-:|:-:|
|履歴なし|![履歴なし.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/67b6895c-9ee6-c074-3971-2c18978b29cb.jpeg)|![履歴なし_合成.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/d629d413-082b-7116-cd2f-0efed3a440c0.jpeg)|
|履歴あり|![履歴あり.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/d55f9f3b-52a1-7c48-84e4-3ee4e1055f56.jpeg)|![履歴あり_合成.jpg](https://qiita-image-store.s3.amazonaws.com/0/67356/cb3c1d0a-f531-87cd-013a-f1e9cad096ba.jpeg)|


# おわりに

ステートマシン図を用いた状態遷移テストの注意点を挙げてみました。
ステートマシン図では複雑な状態遷移をできるだけ簡潔に記述するための様々な記法があります。UMLの記法を駆使することで、設計者は実現したい機能を容易に／簡潔にモデリングできます。
ステートマシン図は状態遷移図よりも情報の密度が高いです。そのため、UMLの記法を意識して、ステートマシン図の振る舞いを正しく理解することで効率の良いテストの実現を目指していきましょう。

[ソフトウェアテスト Advent Calendar 2018](https://qiita.com/advent-calendar/2018/softwaretesting) の明日(5日目)は @____rina____ さんの [受託開発テスターと受託リモートワークテスターとWebサービステスターは何が違ったのか](http://underscore42rina.hatenablog.com/entry/adventcalendar2018) です。