ペアワイズ法によるテストケース抽出ツール「PICT」を使ってテストケースを85%削減する

「 **品質を保ちながら、リグレッションテストの項目数を削減することはできないか？** 」（というよりは、「 **なんか同じようなテストを何回も行っていないか？**」）」と感じている開発者は多いのではないでしょうか。

「ペアワイズ法」と呼ばれるテストケース抽出手法を使えば、テストケースを大幅に削減できるかもしれません。 **本稿で想定したリグレッションテストでは約85%もテストケースを削減することができました。**

本稿では、 **ペアワイズ法によってテストケースを抽出してくれるツール「PICT」** を使って、どのくらいテストケースを削減できるのかを紹介します。

**確認した動作環境**

- OS: macOS Sierra 10.12.5

## ペアワイズ法（オールペア法）とは

ペアワイズ法（オールペア法）は、 **ソフトウェアのバグの多くが1つまたは2つの因子の組み合わせによって発生している** という事実に基づいてテストケースを作成する方法です。

実験計画法では、テストケースの組み合わせを表現する際に以下のような用語を使用します。

- **因子**: テスト対象の項目（判定または条件）
- **水準**: 因子の取り得る値
- **強さ**: 因子の組み合わせ数

例えば、1因子（条件）当たり2個（真偽）の水準があるとき、因子が10個あれば、すべての水準の組み合わせは2^10 ＝ 1024個になります。

ペアワイズ法は、すべての因子の組み合わせでなく、 **2組の因子（強さ2）** における水準の組み合わせをすべて網羅することによってテストケースを制限したものです。

## テストケース生成ツール「PICT」をインストールする

### 「PICT（Pairwise Independent Combinatorial Testing tool）」とは
「PICT」は、Microsoftが公開している、ペアワイズ法によってテストケースを生成するためのオープンソース・ソフトウェア（MIT License）です。

### PICTをインストールする

以下のコマンドを入力することで簡単にインストールすることができます。

```
$ git clone https://github.com/Microsoft/pict.git
$ cd pict/
$ make
$ sudo install -m 0755 pict /usr/local/bin/pict
```

PICTの使い方については以下のウェブサイトが大変参考になるため、本稿では割愛します。

- GitHub『[Microsoft/pict](https://github.com/Microsoft/pict/blob/master/doc/pict.md)』
- Qiita『[テストの数を減らそう！プリキュアで学ぶPICT](http://qiita.com/greymd/items/ad18aa44d4159067a627)』

## 効率的な複合条件のテストケースを求める

例えば、あるプログラムにおいて水準2の因子が20個ある場合、複合条件テストをすべて実施するためには、2^20 = 1,048,576、 **約10万通りもテストしなければならず、とても現実的ではありません。**

ではPICTを使用してペアワイズ法で抽出した場合はどうなるでしょうか。以下のようなテキストファイルを用意します。

getMCC.txt

```
条件01: T, F
条件02: T, F
条件03: T, F
条件04: T, F
条件05: T, F
条件06: T, F
条件07: T, F
条件08: T, F
条件09: T, F
条件10: T, F
条件11: T, F
条件12: T, F
条件13: T, F
条件14: T, F
条件15: T, F
条件16: T, F
条件17: T, F
条件18: T, F
条件19: T, F
条件20: T, F
```

ファイルの準備ができたら、以下のコマンドを入力します。

```
$ pict getMCC.txt /s /o:2
Combinations:   760
Generated tests:11
```

- `/s` : 組み合わせ数を表示する
- `/o:n`: 強さ`n`で組み合わせを求める

ここで、`Generated tests`の値が実際に必要なテストケース数を示します。なんと、 **たった11通りのテストケースだけ実施すればよい** ということが分かります。

```
$ pict getMCC.txt /o:2
条件01	条件02	条件03	条件04	条件05	条件06	条件07	条件08	条件09	条件10	条件11	条件12	条件13	条件14	条件15	条件16	条件17	条件18	条件19	条件20
F	T	F	T	T	F	T	F	T	F	T	T	T	F	T	F	T	T	F	T
T	F	T	F	F	T	F	T	F	T	F	F	F	T	F	T	F	F	F	F
F	T	F	F	T	T	T	T	F	F	T	F	T	T	T	T	F	T	T	F
F	F	T	T	F	F	F	F	T	T	F	F	F	F	F	F	T	F	T	T
T	F	F	T	F	F	T	T	T	T	F	T	T	T	T	T	T	F	T	F
T	T	T	F	T	T	F	F	F	F	F	T	F	T	F	F	F	T	T	T
T	T	F	F	T	F	F	T	F	T	T	T	T	F	F	F	F	F	F	F
T	F	T	T	F	T	T	F	F	T	T	T	F	F	T	T	T	T	F	F
F	T	T	F	F	T	F	T	T	F	T	T	T	T	T	T	F	F	F	T
T	F	F	T	T	T	T	F	F	F	T	F	F	F	F	T	F	T	T	T
F	T	T	F	F	T	F	F	F	T	F	F	T	T	T	T	T	F	T	T
```

これだけのテストパターンでソフトウェアの品質を向上させることができるのであれば、テスト項目として追加すべきでしょう。



## リグレッションテストのテスト項目を削減する

PICTを使えば **リグレッションテストのテスト項目を大幅に削減することができます。**

ここで、本稿おける要件は以下の通りとします。

- OS: Windows 7, Windows 8.1, Windows 10, Mac OS 10.12, iOS 10, iOS 11, Android 7, Android 8
- ブラウザ: Chrome 62, IE 10, IE 11, Firefox, Edge 40, Safari 10, iOS Safari, Android Chrome
- 会員: レギュラー, ゴールド, プラチナ, ダイヤモンド
- カード: なし, VISA, Mastercard, JCB, American Express

すべての水準の組み合わせをテストするには、テストケースはいくつ必要でしょうか。テストに求められる要件を以下のようなテキストファイルとして作成し、PICTで解析してみましょう。

getRegressionTestCase.txt

```
OS: Windows 7, Windows 8.1, Windows 10, Mac OS 10.12, iOS 10, iOS 11, Android 7, Android 8
ブラウザ: Chrome 62, IE 10, IE 11, Firefox, Edge 40, Safari 10, iOS Safari, Android Chrome
会員: レギュラー, ゴールド, プラチナ, ダイヤモンド
カード: なし, VISA, Mastercard, JCB, American Express

IF [OS] = "Windows 7"
  OR [OS] = "Windows 8.1"
  THEN NOT (
    [ブラウザ] like "Edge*"
  );
IF [OS] = "Windows 10"
    THEN (
        [ブラウザ] like "Edge*"
        OR [ブラウザ] = "IE 11"
    );
IF [OS] like "Windows*"
  THEN NOT (
    [ブラウザ] like "Safari*"
    OR [ブラウザ] like "iOS*"
    OR [ブラウザ] like "Android*"
  );
IF [OS] like "Mac OS*"
  THEN NOT (
    [ブラウザ] like "IE*"
    OR [ブラウザ] like "Edge*"
    OR [ブラウザ] like "iOS*"
    OR [ブラウザ] like "Android*"
  );
IF [OS] like "iOS*"
  THEN [ブラウザ] like "iOS*";
IF [OS] like "Android*"
  THEN [ブラウザ] like "Android*";
```

### 因子を全網羅（強さ4）する場合
以下のコマンドを入力して確認してみましょう。

```
$ pict getRegressionTestCase.txt /s /o:4
Combinations:   340
Generated tests:340
Generation time:0:00:00
```

必要なテストケース数は340ということが分かりました。

### ペアワイズ法で抽出する場合

```
$ pict getRegressionTestCase.txt /s /o:2
Combinations:   181
Generated tests:50
Generation time:0:00:00
```

テストケース数は50となりました。これは因子を全網羅した場合に比べて、 **工数を約85%削減** できることを示しています。

以下のコマンドを入力すると、テストケースが出力されます。

```
$ pict getRegressionTestCase.txt
OS	ブラウザ	会員	カード
Mac OS 10.12	Chrome 62	レギュラー	VISA
Mac OS 10.12	Safari 10	ゴールド	なし
Android 7	Android Chrome	ダイヤモンド	American Express
Windows 10	Edge 40	プラチナ	JCB
iOS 10	iOS Safari	レギュラー	Mastercard
iOS 11	iOS Safari	ダイヤモンド	JCB
Mac OS 10.12	Safari 10	プラチナ	Mastercard
Windows 8.1	IE 10	レギュラー	なし
iOS 11	iOS Safari	ゴールド	Mastercard
Windows 8.1	Chrome 62	ゴールド	JCB
Windows 10	Edge 40	ダイヤモンド	なし
Windows 7	Firefox	プラチナ	なし
Windows 8.1	IE 11	プラチナ	American Express
Mac OS 10.12	Safari 10	レギュラー	American Express
Windows 10	IE 11	ゴールド	なし
Android 7	Android Chrome	ダイヤモンド	Mastercard
Windows 10	Edge 40	レギュラー	Mastercard
Windows 7	Firefox	ゴールド	American Express
Mac OS 10.12	Safari 10	ダイヤモンド	JCB
Android 8	Android Chrome	プラチナ	VISA
Windows 7	IE 10	ダイヤモンド	JCB
Windows 7	IE 11	レギュラー	Mastercard
Android 8	Android Chrome	レギュラー	JCB
Mac OS 10.12	Safari 10	ダイヤモンド	VISA
Android 8	Android Chrome	ゴールド	なし
Android 8	Android Chrome	ダイヤモンド	Mastercard
iOS 11	iOS Safari	プラチナ	なし
Windows 10	Edge 40	ゴールド	American Express
iOS 11	iOS Safari	レギュラー	American Express
Windows 8.1	IE 11	ダイヤモンド	JCB
Windows 8.1	Firefox	ダイヤモンド	Mastercard
Android 7	Android Chrome	ゴールド	VISA
Windows 8.1	IE 10	プラチナ	Mastercard
Windows 7	Firefox	レギュラー	VISA
iOS 10	iOS Safari	ダイヤモンド	JCB
iOS 10	iOS Safari	プラチナ	VISA
Windows 8.1	IE 10	ゴールド	VISA
Android 8	Android Chrome	プラチナ	American Express
Windows 7	Chrome 62	プラチナ	なし
Windows 10	Edge 40	ダイヤモンド	VISA
iOS 10	iOS Safari	ゴールド	なし
Windows 8.1	Chrome 62	ダイヤモンド	American Express
iOS 10	iOS Safari	レギュラー	American Express
Windows 7	Chrome 62	レギュラー	Mastercard
Mac OS 10.12	Firefox	プラチナ	JCB
Android 7	Android Chrome	プラチナ	なし
Android 7	Android Chrome	レギュラー	JCB
Windows 10	IE 11	ダイヤモンド	VISA
iOS 11	iOS Safari	プラチナ	VISA
Windows 8.1	IE 10	ダイヤモンド	American Express
```

テキスト形式だと分かりづらいので、出力結果を表形式でまとめてみました。

| OS           | ブラウザ       | 会員         | カード           |
|--------------|----------------|--------------|------------------|
| Mac OS 10.12 | Chrome 62      | レギュラー   | VISA             |
| Mac OS 10.12 | Safari 10      | ゴールド     | なし             |
| Android 7    | Android Chrome | ダイヤモンド | American Express |
| Windows 10   | Edge 40        | プラチナ     | JCB              |
| iOS 10       | iOS Safari     | レギュラー   | Mastercard       |
| iOS 11       | iOS Safari     | ダイヤモンド | JCB              |
| Mac OS 10.12 | Safari 10      | プラチナ     | Mastercard       |
| Windows 8.1  | IE 10          | レギュラー   | なし             |
| iOS 11       | iOS Safari     | ゴールド     | Mastercard       |
| Windows 8.1  | Chrome 62      | ゴールド     | JCB              |
| Windows 10   | Edge 40        | ダイヤモンド | なし             |
| Windows 7    | Firefox        | プラチナ     | なし             |
| Windows 8.1  | IE 11          | プラチナ     | American Express |
| Mac OS 10.12 | Safari 10      | レギュラー   | American Express |
| Windows 10   | IE 11          | ゴールド     | なし             |
| Android 7    | Android Chrome | ダイヤモンド | Mastercard       |
| Windows 10   | Edge 40        | レギュラー   | Mastercard       |
| Windows 7    | Firefox        | ゴールド     | American Express |
| Mac OS 10.12 | Safari 10      | ダイヤモンド | JCB              |
| Android 8    | Android Chrome | プラチナ     | VISA             |
| Windows 7    | IE 10          | ダイヤモンド | JCB              |
| Windows 7    | IE 11          | レギュラー   | Mastercard       |
| Android 8    | Android Chrome | レギュラー   | JCB              |
| Mac OS 10.12 | Safari 10      | ダイヤモンド | VISA             |
| Android 8    | Android Chrome | ゴールド     | なし             |
| Android 8    | Android Chrome | ダイヤモンド | Mastercard       |
| iOS 11       | iOS Safari     | プラチナ     | なし             |
| Windows 10   | Edge 40        | ゴールド     | American Express |
| iOS 11       | iOS Safari     | レギュラー   | American Express |
| Windows 8.1  | IE 11          | ダイヤモンド | JCB              |
| Windows 8.1  | Firefox        | ダイヤモンド | Mastercard       |
| Android 7    | Android Chrome | ゴールド     | VISA             |
| Windows 8.1  | IE 10          | プラチナ     | Mastercard       |
| Windows 7    | Firefox        | レギュラー   | VISA             |
| iOS 10       | iOS Safari     | ダイヤモンド | JCB              |
| iOS 10       | iOS Safari     | プラチナ     | VISA             |
| Windows 8.1  | IE 10          | ゴールド     | VISA             |
| Android 8    | Android Chrome | プラチナ     | American Express |
| Windows 7    | Chrome 62      | プラチナ     | なし             |
| Windows 10   | Edge 40        | ダイヤモンド | VISA             |
| iOS 10       | iOS Safari     | ゴールド     | なし             |
| Windows 8.1  | Chrome 62      | ダイヤモンド | American Express |
| iOS 10       | iOS Safari     | レギュラー   | American Express |
| Windows 7    | Chrome 62      | レギュラー   | Mastercard       |
| Mac OS 10.12 | Firefox        | プラチナ     | JCB              |
| Android 7    | Android Chrome | プラチナ     | なし             |
| Android 7    | Android Chrome | レギュラー   | JCB              |
| Windows 10   | IE 11          | ダイヤモンド | VISA             |
| iOS 11       | iOS Safari     | プラチナ     | VISA             |
| Windows 8.1  | IE 10          | ダイヤモンド | American Express |

## まとめ

**PICTはテストの品質を落とさず、テスト工数を大幅に削減する効果が期待できます。** 膨大なテスト工数に悩んでいるプロジェクトは「PICT」の導入を検討すると良いかもしれません。

## 参考としたウェブサイト

- ＠IT『[組み合わせテストを科学的に効率化する――手法とツール、品質保証のための道具](http://www.atmarkit.co.jp/ait/articles/1503/16/news149.html)』
- JaSST'14 Tokyo『[直交表とオールペア法の並行運用 によるソフトウェアテスト](http://jasst.jp/symposium/jasst14tokyo/pdf/C4-1-1.pdf)』