ペアワイズ法でテストケースを85%削減する(ムダなテストしていませんか?)

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

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

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

確認した動作環境

  • OS: macOS Sierra 10.12.5

ホワイトボックステストにおけるカバレッジについて

ペアワイズ法を学ぶにあたって、まずはテストカバレッジの種類について復習しましょう。ここでは以下のサンプルコードを用いて、それぞれのカバレッジについて説明します。

サンプルコード

if(条件A1 || 条件A2){ // 判定文A
  命令文X;
}

if(条件B1 || 条件B2){ // 判定文B
  命令文Y;
}

命令網羅 (statement coverage) (C0)

それぞれの命令文が少なくとも1回は実行される ようにテストを設計します。上記のサンプルコードの場合、テストケース数は1通りとなります。

命令文X 命令文Y
o o

分岐網羅 (branch coverage) (C1)

それぞれの判定文における真偽が少なくとも1回は実行される ようにテストを設計します。上記のサンプルコードの場合、テストケース数は2通りとなります。

判定文A 判定文B
T T
F F

条件網羅 (condition coverage) (C2)

それぞれの条件における真偽が少なくとも1回は実行される ようにテストを設計します。上記のサンプルコードの場合、テストケース数は2通りとなります。

条件A1 条件A2 条件B1 条件B2
T T T T
F F F F

複合条件網羅 (multiple condition coverage) (MCC)

それぞれの条件における真偽の組み合わせがすべて実行される ようにテストを設計します。上記のサンプルコードの場合、テストケース数は2^4 = 16通りとなります。

条件A1 条件A2 条件B1 条件B2
T F T T
F F F T
T F F T
T T F T
F T T T
F F T F
T T T T
F T F T
T F F F
T T F F
F T F F
F F T T
T F T F
T T T F
F T T F
F F F F

ペアワイズ法(オールペア法)とは

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

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

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

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

ペアワイズ法は、すべての因子の組み合わせでなく、 2組の因子(強さ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の使い方については、pict/pict.md at master · Microsoft/pict · GitHubまたはテストの数を減らそう!プリキュアで学ぶPICT - Qiitaが大変参考になるため、本稿では割愛します。

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

例えば、あるプログラムにおいて水準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

ここで、 一つの条件における全画面遷移確認にかかる時間を30分 とします。すべての水準の組み合わせをテストするには、テストケースはいくつ必要でしょうか。

テストに求められる要件を以下のようなテキストファイルとして作成し、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となり、すべてのテストを終えるには0.5[時間] × 340[ケース] / 8[時間/人日] = 21.25人日 もの工数がかかってしまいます。

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

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

テストケース数は50となり、すべてのテストを終えるには0.5[時間] × 50[ケース] / 8[時間/人日] = 3.125人日 の工数で済みます。これは因子を全網羅した場合に比べて、 工数を約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

まとめ

ペアワイズ法がこんなにも効果的な手法である とは思っていませんでした。テスト手法についてもう少し学習して、いつかペアワイズ法を現場で取り入れてみたいと思います。


クリエイティブ・コモンズ・ライセンス
この 作品 は クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。