ソフトウェア機能テスト手法まとめ

# テスト手法まとめ

## ブラックボックステスト

ブラックボックステストとは、要件や仕様に基づいてテストを行う戦略。
ソフトウェア内部の知識を必要としない。

### 同値クラステスト

同値クラスとはモジュールで同等に処理される、あるいは同じ結果を返すデータの集合。

1. 同値クラスを定義
2. 定義したクラスから代表値を選ぶ
3. テストケースを作成す

#### 同値クラステスト：例
「16歳から20歳のみ受け入れる」場合
![同値クラス.png](https://qiita-image-store.s3.amazonaws.com/0/58991/aab6cce6-1bf3-63ed-756e-bfda8ef384e5.png)

同値クラスは3つあり、それぞれに属する任意の値を代表値にする。 

### 境界値テスト

同値クラスの境界をテストする。以下の手順で行う。

1. 同値クラスを見つける
1. 同値クラスの境界を見つける
1. 同値クラスの境界について、すぐ上、すぐ下、境界上の値についてテストケースを作成する

#### 境界値テスト：例
「16歳から20歳のみ受け入れる」場合

![境界値.png](https://qiita-image-store.s3.amazonaws.com/0/58991/ab1cebe3-8ad6-86fe-6c05-132b302650b7.png)

### ドメイン分析テスト

同時に複数の変数をテストする方法。

1. ポイントを抽出
2. ドメインテストマトリックスを記述
3. テストケース作成

#### ドメイン分析テスト：用語定義

| 用語        | 意味                                         |
| ----------- | -------------------------------------------- |
| onポイント  | 境界上の値                                   |
| offポイント | 境界と隣接する、onポイントと逆の結果となる値 |
| inポイント  | 条件を満たすが、境界上ではない値             |
| outポイント | 条件を満たさない境界上ではない値             

- onポイントが条件を満たす値なら(境界が`'<='`もしくは`'>='`)、offポイントは条件を満たさない値
- onポイントが条件を満たさない値なら(境界が`'<'`もしくは`'>'`)、offポイントは条件を満たす値

### ドメイン分析テスト:ポイントの例

「16歳から20歳のみ受け入れる」場合

#### `16 <= val <= 20`

| ポイント | 値       |
| -------- | -------- |
| on       | 16, 20   |
| off      | 15, 21   |
| in       | 17~19    |
| out      | 3, 40... |


#### `15 < val < 21`

| ポイント | 値       |
| -------- | -------- |
| on       | 15, 21   |
| off      | 16, 20   |
| in       | 17~19    |
| out      | 3, 40... |

#### ドメイン分析テスト：ドメインテストマトリックス例

「16歳から20歳かつ、身長160cm以上180cm未満を受け入れる」場合
`16<=年齢<=20 && 160<=身長<=180`

![ドメインテストマトリックス.png](https://qiita-image-store.s3.amazonaws.com/0/58991/026bc3fa-1a22-9261-41f4-3a70e06706aa.png)


- それぞれの境界についてon/offポイントを決め、表に記載する
- 一つの変数がon/offポイントを取るとき、他の変数はinポイントの値を取る
- inポイントの値は任意のものでよい

### デシジョンテーブルテスト
デシジョンテーブルは、内部システム設計を文書化するためのツール。テストケースの作成の指針になる。

#### デシジョンテーブルテスト：例

「会社員かつ運動をしている人を受け入れる」場合、デシジョンテーブルは以下になる。

|                | ルール1 | ルール2 | ルール3 | ルール4 |
| -------------- | ------- | ------- | ------- | ------- |
| 条件           |         |         |         |         |
| 運動をしている | -       | -       | Y       | Y       |
| 会社員である   | -       | Y       | -       | Y       |
| アクション     |         |         |         |         |
| 結果           | ×       | ×       | ×       | ○       |

それぞれのルールの、条件とアクションが入力と期待する結果になる。

### ペア構成テスト
入力とする変数が多い場合に有効。
全ての変数の全ての値の組み合わせをテストするのではなく、変数値の全てのペアをテストする。

#### ペア構成テスト：例
入力が3つあり、それぞれの入力は3種類の値を取る。
全組み合わせをテストすると27通りになるが、ペア構成テストでは10通りとなる。

- OS
  - Windows
  - Mac
  - Linux
- 言語
  - C
  - Python
  - Haskell
- エディタ
  - Memo
  - Emacs
  - Atom

| OS      | 言語    | エディタ |
| ------- | ------- | -------- |
| Windows | C       | Memo     |
| Windows | Haskell | Emacs    |
| Linux   | C       | Atom     |
| Mac     | C       | Emacs    |
| Linux   | Python  | Memo     |
| Mac     | Python  | Atom     |
| Windows | Python  | Emacs    |
| Mac     | Haskell | Memo     |
| Windows | Haskell | Atom     |
| Linux   | Haskell | Emacs    |


テストケースの生成にはMicrosoftのツールPICTが便利。
https://github.com/Microsoft/pict

### 状態遷移テスト
状態遷移図もしくは状態遷移表に従ってテストケースを記述する。

状態遷移図の例
![状態遷移図.png](https://qiita-image-store.s3.amazonaws.com/0/58991/cbcbe4a1-dee5-bc2d-4c45-4874ac9d0808.png)

#### 状態遷移テスト：作成パターン
- すべての状態を一回は訪れるテストケース (テストカバレッジとしては弱い)
- 全ての遷移を1回はテストするテストケース (一般的に推奨)(ループは１回)

### ユースケーステスト
ユースケース図、ユースケース記述に従ってテストケースを作成する。
これまではシステムの一部に対するテストケース設計技法の説明だったが、これは個別のトランザクションに対するテストケース。

ユースケースは入力データを規定していないため、テスト担当者が選択する必要がある。
同値分割・境界値分割・ドメインテストマトリックスなどを使用する。


## ホワイトボックステスト
プログラムの内部パス、構造、実装に基づいて行うテスト戦略。

### ホワイトボックステストの欠点

- すべての実行パスをテストしようとすると、テストが多くなりすぎる
- テストケースの選択によってはデータの値に依存する欠陥を見つけられない。(`b=0`のときの`a/b`など)
- 制御フローが正確であること前提、存在しないパスはテストで発見できない
- テスト担当者にもプログラミングスキルが必要

### 制御フローテスト
プログラムコードのモジュール内の実行パスを識別して、それらのパスを網羅するテストケースを作成する

まずはテストに使用する制御フロー図を作成する。

#### 制御フローテスト：制御フロー図例
![制御フロー図.png](https://qiita-image-store.s3.amazonaws.com/0/58991/5467266b-b80d-6ea4-efbf-6bb858f107a0.png)

#### カバレッジレベル
##### ステートメントカバレッジ (C0) (命令網羅)
全てのステートメントがテスト実行中に少なくとも一回実行される。
見逃されるパスが多くあり、十分なレベルのテストとは言えない。
しかし実際に100%を達成するのは容易ではない。

下記図では、`a>10 && b>10`と`x>20 || y>20`がTrueになるテストケース一つで満たすことができる。

![制御フローテスト_1.png](https://qiita-image-store.s3.amazonaws.com/0/58991/5d925144-4267-d4f5-9fb9-db54155061d9.png)

##### 100%デシジョンカバレッジ (ブランチカバレッジ) (C1) (分岐網羅)
すべての条件判定に対して、True/Falseを少なくとも一回ずつ評価する。
ブランチカバレッジを満たすとステートメントカバレッジも満たされる。

下記図では、以下のテストケースでブランチカバレッジを満たすことができる。

1. `a>10 && b>10`と`x>20 || y>20`がそれぞれTrueとなるテストケース
1. `a>10 && b>10`と`x>20 || y>20`がそれぞれFalseとなるテストケース

![制御フローテスト_2.png](https://qiita-image-store.s3.amazonaws.com/0/58991/7615ea29-8114-6c23-41b7-8e9f4cda3458.png)

###### (注釈) 複雑的循環度 (サイクロマティック数)
プログラム内の線形的に独立な経路の数。
サクロマティック数はブランチカバレッジを満たす最大テストケース数となる。

制御フロー図を使用したときにサイクロマチック数は次の式で計算できる。  
`C=リンク数(矢印)-ノード数(円)+2`  
分岐先が2択のみの場合、`C=条件判定数+1`になる。

##### コンディションカバレッジ (C2) (条件網羅)
全ての個別条件が、「真」と「偽」の両方に少なくとも1回はなるようテストケースを作成する。
`if(a>10 && b>10)`において、`a>10`も`b>10`もテストするテストケースを作成する。
(一般的に言われるコンディションカバレッジが短絡評価を考慮しているのかどうかは分かりませんでした)
個別条件が評価されるだけなので、ブランチカバレッジを満たすわけではない。

##### ブランチ + コンディションカバレッジ
ブランチカバレッジを満たしつつ、コンディションカバレッジを満たす。

##### マルチプルコンディションカバレッジ (複合条件網羅)
個別条件の全ての組み合わせを満たすテストケースを作成する。
`if(a>10 && b>10)`と`if(x>20 || y>20)`の条件式があるとき、個別条件`a>10`, `b>10`, `x>20`, `y>20`の全ての真偽の組み合わせを満たすテストケースは`2パターン^4つ = 16通り`。

##### パスカバレッジ
プログラムが取りうる制御パスを全てテストする。
制御フローテストのカバレッジとして最も高いレベル。

フロー図再掲。

![制御フロー図.png](https://qiita-image-store.s3.amazonaws.com/0/58991/b3468640-73cb-6753-b8ce-30a65680f0a1.png)

上記制御フロー図では制御パスは4種類あり、それぞれを通るテストケースを作成する。

|                | 1    | 2     | 3     | 4     |
| -------------- | ---- | ----- | ----- | ----- |
| a>10 and b>10   | true | false | true  | false |
| x>20 or y>20 | true | true  | false | false |

ループが存在する場合、全てのパスを実行するのは不可能である。
よって、ループの実行数を制御することでテストケースの削減を行う。
ループしない、1回ループ、n回ループ、ループ最大値あたりが有力なテストケースの候補となる。

![制御フローテスト_3-1.png](https://qiita-image-store.s3.amazonaws.com/0/58991/ca48194a-ffe5-e87c-3227-2544958c4c60.png)
![制御フローテスト_3-2.png](https://qiita-image-store.s3.amazonaws.com/0/58991/3d324873-e3e0-5f08-9b2d-534b7b1d87ba.png)


### データフローテスト

変数の定義・使用・消滅に着目したテスト。コーディングミスによって変数の値が不正な使用のされ方をしている場所を見つけるのに有用である。

変数の定義・使用・消滅に着目したとき、以下のような状況が考えられる。

|            | 状況                 | 判断                 |
| ---------- | -------------------- | -------------------- |
| 定義-定義 | 再定義               | 不正ではないが要注意 |
| 定義-使用  | 定義されてから使用   | 正常                 |
| 定義-消滅  | 使用されずに消滅     | 不正ではないが要注意 |
| 使用-定義  | 使用されたあとに定義 | 正常                 |
| 使用-使用  | 再使用               | 正常                 |
| 使用-消滅  | 使用されてから消滅   | 正常                 |
| 消滅-定義 | 消滅したあとに定義   | 正常                 |
| 消滅-使用  | 消滅したあとに使用   | 不正                 |
| 消滅-消滅  | 消滅したあとに消滅   | 不正ではないが要注意 |

上記表の不正や要注意の状況を、変数の定義・使用・消滅に着目した制御フロー図から見つける。

![データ用制御フロー図.png](https://qiita-image-store.s3.amazonaws.com/0/58991/efb238ff-1951-c505-66f0-520f911da54d.png)