テスト初心者が知っておくべきブラックボックステストの種類と概要

テスト初心者がいきなりテストケースを考えようとしても、最初から適切なテストケースを書いて品質やテストの効率性を高めることは難しいです。
今回はテストの中でもユーザ側に立った**ブラックボックステスト**の種類と概要を見てみます。

# ブラックボックステスト
ブラックボックステストは、ソフトウェアが要件や仕様を満たしているかを確認するためのテストです。
「実際に関数が何をしているのか」といった具体的な実装に関する知識は必要としません。
要件定義書を元にしてテストケースを考えます。
ブラックボックステストは、単体テスト・統合テスト・システムテスト・受け入れテストといった全てのレベルのテストで行うことができます。

- **単体テスト**：ソフトウェアの最小単位で行うテスト、関数やクラスなど
- **統合テスト**：単体を組み合わせたときの挙動を確認するテスト、複数の関数を利用するプログラムなど
- **システムテスト**：ソフトウェア全体から構成されるテスト、機能性やユーザビリティ、セキュリティなど様々なタイプが存在する
- **受け入れテスト**：顧客がソフトウェアを受け入れる条件となるテスト

**メリット**
ソフトウェアの入出力をすべて網羅する必要がないため、テストにかけるコストに対して最大限の効果を得ることができます。

**デメリット**
ソフトウェアをどの部分までテストできたか把握しづらく、どうしても見逃してしまう欠陥があります。

## 同値クラステスト
同値クラステストは、多くのエンジニアが無意識のうちに行なっている最も基本的なテストです。
入力値をある範囲ごとのクラスに分けてテストケースを考えます。
十分なテストカバレッジを保ちながら、テストケースを現実的な数に減らすことができます。

### 具体例
BMIと肥満度の判定では、以下のような分類になっています。

|BMI|判定|
|---|---|
|18.5未満|低体重|
|18.5以上25未満|普通|
|25以上30未満|肥満1度|
|30以上35未満|肥満2度|
|35以上40未満|肥満3度|
|40以上|肥満4度|

この場合、BMI=1, 2, 3...と順に検証していく必要はありません。
例えば18.5未満の場合は2でも9でも18でも結果が同じになるので、この範囲であればどの値を選んでも範囲内の他の値と同じ程度に有効です。
このように、期待されるレスポンスが同じ範囲のことを**同値クラス**といいます。

### 適用対象
この技法が適しているのは、入力データの大半が一定の範囲内の値をとるようなシステムです。
同値クラステストは、単体テスト・統合テスト・システムテスト・受け入れテストでそれぞれ同じように適用できます。


## 境界値テスト
境界値テストは同値クラステストから導き出された考え方で、同値クラスの境界に着目します。
境界には多くの欠陥が潜んでいる可能性が高いため、境界付近の値を選んでテストケースを作ります。

### 具体例
先ほどと同様にBMIで考えてみます、もし判定が以下のような表で行われていたらどうでしょう。

|BMI|判定|
|---|---|
|〜18.5|低体重|
|18.5〜25|普通|
|25〜30|肥満1度|
|30〜35|肥満2度|
|35〜40|肥満3度|
|40〜|肥満4度|

上の条件からみていくと、BMI=18.5は低体重と判別できそうですが、2つ目の条件を見ると普通にも当てはまりそう…となってしまいます。
本来は同値テストの例のような判定をしたいのだとしたら、ここでは18.5や40などの値を選ぶことで、早期に欠陥を見つけ出すことができます。

### 適用対象
この技法が適しているのは、同値クラステストと同じように入力データの大半が一定の範囲内の値をとり、境界値を識別できるシステムです。
境界値テストは、単体テスト・統合テスト・システムテスト・受け入れテストでそれぞれ同じように適用できます。

## デシジョンテーブルテスト
デシジョンテーブルテストは、デシジョンテーブル(条件の集合に基づいてビジネスルールを表現するもの)に基づいて行われるテストです。

### 具体例
例えば「３０歳以下で子供がいる場合に割引する」という要件があったとします。
これをデシジョンテーブルで表現すると以下のようになります。

||ルール1|ルール2|ルール3|ルール4|
|-----|-----|-----|-----|-----|
|条件||||
|３０歳以上か|Yes|Yes|No|No|
|子供がいるか|Yes|No|Yes|No|
|||||
|アクション||||
|割引|する|しない|しない|しない|

縦の各ルールがそのままテストケースになり、「条件」が入力、「アクション」が期待される結果となります。
Yes/Noのような2値以外の条件を設定したり、複数のアクションを設定することも可能です。

||ルール1|ルール2|ルール3|ルール4|
|-----|-----|-----|-----|-----|
|条件||||
|条件1|０以上１０未満|１０以上20未満|20以上30未満|30以上40未満|
|条件２|5|6 or 7|8|9<|
|||||
|アクション||||
|アクションA|Xをする|Yをする|Xをする|Yをする|
|アクションB|Aをする|Aをする|Bをする|Bをする|

テストケースは各ルールに対して少なくとも1つは作成する必要があり、２値以外の条件では複数用意する必要がある可能性があります(範囲指定の条件であれば範囲の上端と下端など)

### 適用対象
デシジョンテーブルテストは、システムが複雑なビジネスルールを持っており、そのビジネスルールがある条件の組み合わせで表現でき、何らかのアクションと紐づく場合に適用することができます。
単体テスト・統合テスト・システムテスト・受け入れテストでそれぞれ同じように適用できます。

## ペア構成テスト
ペア構成テストは、テストすべき組み合わせが非常に多い場合に有効なテストです。
ペア構成テストでは「全ての変数の全ての値の全ての組み合わせ」ではなく「**変数値のすべてのペア**」をテストします。
こうすることによって、テストケースは大幅に減らすことができます。

システムにおける欠陥は、ほとんどの場合シングルモード欠陥(特定の機能のみが単に動かない場合)かダブルモード欠陥(特定の機能を組み合わせた時にだけ動かなくなる場合)があり、ペア構成テストではシングルモードとダブルモード全ての欠陥をテスト可能な、テストケースの最小のサブセットを見つけ出すことができます。

すべてのペアを見つけ出すには、**直交表**という手法があります。
AとBのペアを考えてみましょう。
AとBの組み合わせは[A,A], [A,B], [B,A], [B,B]の４つがあります。
直交表は数字の入った２次元の配列で、配列から任意の2つの列を選ぶと、 列のペアをどのように選んだとしても全てのペアの組み合わせが現れます。

| |1|2|3|
|----|----|----|----|
|1|1|1|1|
|2|1|2|2|
|3|2|1|2|
|4|2|2|1|

わかりにくいですが、一番上の行と一番左の列は単なる番号の参照です。
ここで、先ほどの{A, B}を{1, 2}にあてはめてみましょう。

| |1|2|3|
|----|----|----|----|
|1|A|A|A|
|2|A|B|B|
|3|B|A|B|
|4|B|B|A|

それでは、列1と列２で確かめてみます。
組み合わせは、[A,A], [A,B], [B,A], [B,B]となり全ての組み合わせが現れています。
つぎに、列１と列３で確かめてみます。
組み合わせは、[A,A], [A,B], [B,B], [B,A]となり、順番は変わりましたが全ての組み合わせが現れています。

必要になるのは、列の数が変数の数と同じ以上で、各変数のとりうる値の数に対応する値が列に含まれているような直交表です。

### 具体例
例えば、システムがfoo, bar, hoge. piyoつの異なる入力を持ち、A, B, Cの3つの値のどれかをとるとします。

変数の数は4, とりうる値は3つなので、これに合う直交表を探すと、L9直交表が対応します。
列番号を省くと以下のような表になります。

|1|2|3|4|
|----|----|----|----|
|1|1|1|1|
|1|2|2|2|
|1|3|3|3|
|2|1|2|3|
|2|2|3|1|
|2|3|1|2|
|3|1|3|2|
|3|2|1|3|
|3|3|2|1|

これに値{A, B, C}を当てはめてみましょう。


|1|2|3|4|
|----|----|----|----|
|A|A|A|A|
|A|B|B|B|
|A|C|C|C|
|B|A|B|C|
|B|B|C|A|
|B|C|A|B|
|C|A|C|B|
|C|B|A|C|
|C|C|B|A|

列１と列２をみると、[A,A], [A,B], [A,C], [B,A], [B,B], [B,C], [C,A], [C,B], [C,C]の全てのペアが入っています。

このように、組み合わせの数は３の4乗で81になりますが、入力の全ての値のペアを網羅するだけなら9個のテストケースで済みます。

### 適用対象
ペア構成テストは、入力の組み合わせの数が大きい時に適用することができます。
単体テスト・統合テスト・システムテスト・受け入れテストでそれぞれ同じように適用できます。

## 状態遷移図テスト
状態遷移図テストは、状態遷移図をもとにテストケースを作成するテストです。
状態遷移図は、システム要求を把握し、システムが受け取って処理するイベントを図に起こしたものです。
これによりテストすべき状態、イベント、アクション、遷移を明確にすることができ、さらにイベントの有効・無効な順番やシステム外部との相互作用も把握することができます。
このテストでは、状態遷移図を作成し、全ての遷移を少なくとも1回は実行するようなテストケースを作成します。

### 具体例
あるECサイトでの購入フローを考えてみます。
カートに入れてから到着するまでの購入フローは、以下の状態遷移図で表せます。

![Untitled Diagram (14).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196629/5db3ccb6-2fe4-9cfd-da36-ea36650bb0b2.png)

全ての遷移を実行することを考えると、テストケースはこのようになります。

![Untitled Diagram (15).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196629/8acd5e40-d038-d426-535d-89d8df01865a.png)

### 適用対象
状態遷移図テストは、システム要求が状態とその遷移を記述している場合に適用でき、システムが状態を持たない時や外部からのリアルタイムなイベントに対応する必要のない場合は適用できません。
システムテストや受入れテストで行います。

## ユースケーステスト
ユースケーステストでは、個別のトランザクションを1つ1つテストすることでシステムの機能を通しで実行できるようなテストケースを設計します。トランザクションを要件定義で記述するにはフローチャートや文章など色々な方法がありますが、一般的なアプローチはユースケース図を利用することです。

ユースケースとは、アクターがある目的を達成するためにシステムをどう使うかを示すシナリオです。
ユースケースはシステム側の視点ではなく、ユーザー側の視点から定義されます。

![Untitled Diagram (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196629/34846378-fc6f-670d-31cf-f5db79f313a9.png)

ユースケース図は通常は上記のように書きますが、これでは詳細度のレベルが開発者にとってもテスト担当者にとっても十分とは言えないため、Alistair Cockburnが提案したユースケースを詳細に記述するためのテンプレートを利用します。
以下は彼のテンプレートをテストに応用したものとなります。

|ユースケースの構成要素|説明|
|------------------|---|
|ユースケース番号または識別子|ユースケースの一意の識別子|
|ユースケース名|能動態の動詞を使って目的を表す|
|その状況における目的|必要があれば目的の詳細な記述を行う|
|スコープ|企業 or システム or サブシステム|
|レベル|要約 or 主タスク or サブ機能|
|主アクター|ロールの名前または主アクターの記述|
|事前条件|ユースケースの起動まえにシステムに要求される状態|
|成功時の事後条件|ユースケースが成功して完了した時のシステムの状態|
|失敗時の事後条件|ユースケースが失敗して完了した時のシステムの状態|
|トリガー|ユースケースを起動するアクション|
|主成功シナリオ|ステップとアクション|
|拡張|主成功シナリオが多様化する条件および多様化したシナリオの記述|
|バリエーション|メインのフローには影響を与えないが考慮するべきバリエーション|
|優先度|重要さの度合い|
|応答時間|ユースケース実行に要する時間|
|頻度|ユースケースが実行される頻度|
|主アクターへのチャネル|対話型 or ファイル or データベース...|
|2次アクター|ユースケース実行に必要な他のアクター|
|2次アクターへのチャネル|対話型 or ファイル or データベース...|
|納期|スケジュール情報|
|完全性レベル|ユースケースを識別(0.1) or 主シナリオを定義(0.5) or 全ての拡張を定義(0,8) or 全項目が満たされた(1,0)|
|懸念事項|決定を待っている未解決な課題|

### 具体例
上記のテンプレートにそって、大学の履修登録システムを考えてみます。
学生がある科目を登録しようとしています。

|ユースケースの構成要素|説明|
|------------------|---|
|ユースケース番号または識別子|REG0001|
|ユースケース名|科目への登録|
|その状況における目的||
|スコープ|システム|
|レベル|主タスク|
|主アクター|学生|
|事前条件|なし|
|成功時の事後条件|学生が該当科目に登録|
|失敗時の事後条件|学生の科目リストが変更されない|
|トリガー|学生が科目を選択し登録する|
|主成功シナリオ|下に記述|
|拡張|下に記述|
|バリエーション|学生がPCまたはスマートフォンを利用する|
|優先度|最重要|
|応答時間|10秒以下|
|頻度|５科目に対して4週間に渡って1000人の学生が登録する|
|主アクターへのチャネル|対話型|
|2次アクター|なし|
|2次アクターへのチャネル||
|納期|2020年1月|
|完全性レベル|0.5|
|懸念事項|なし|

主成功シナリオ

|ステップ|アクション|
|------|-------|
|1|A:「科目の登録」を選択する|
|2|A:科目を選択する|
|3|S：科目説明を表示する|
|4|A:クラスを選択する|
|5|S:クラスの曜日と時間を表示する|
|6|A:受け入れる|
|7|S:科目/クラスを学生の科目リストに追加する|

拡張

|ステップ|アクション|
|------|-------|
|2a|科目が存在しない<br>S:メッセージを表示し終了|
|4a|クラスが存在しない<br>S:メッセージを表示し終了|
|4b|クラスが定員一杯<br>S:メッセージを表示し終了|
|6a|学生が受け入れない<br>S:メッセージを表示し終了|

### 適用対象
ユースケーステストは、システムのトランザクションが十分に定義されている場合に適用できます。
システムテストと受け入れテストのテストケースを開発するための基盤として利用します。


# 参考
- [はじめて学ぶソフトウェアのテスト技法](https://amzn.to/2K2h6vL)