PICTというツール

こんにちは。クラスメソッド開発部の森永です。 プロジェクトを運営していると、様々な要因でスケジュールが切迫してくることがしばしばありますよね。その時に割を食うのが、テスト工程だったりします。充分に確保できない期間の中で、どれだけシステムを枯れさせられるのか。おそらく、悩んでいらっしゃる方も多いことと思います。システム屋にとっては、幸せの青い鳥のような―(苦笑)

そこで注目したいのが、テストケース生成ツールです。膨大なテスト項目を、理論に基づいて圧縮して(削減して)くれます。これで少しでも余裕ができれば、不具合検出の精度も上がるというものです。SE生活十数年、やっと青い鳥の尻尾が掴めるか。
今回使用するのは、MicrosoftのPICT(Pairwise Independent Combinatorial Testing tool)というツールです。フリーながらかなり高機能で、Microsoftでは2000年から実際の現場で使われているそうです。つまり、あのMicrosoftも効果を認めているツールだという訳です。 PICTはペア・ワイズ法(またはオール・ペア法ともいう)という理論に基づいています。複数のパラメタ値のうち、可能性のある(初期設定では)2つの値の組み合わせを網羅したテストケースを生成します。

何だか、よく分かりませんね。論より証拠、早速使ってみましょう。

PICTのインストール:

まず、下記のURLからPICTをダウンロードして下さい。

  http://www.pairwise.org/tools.asp

ダウンロードしたmsi形式のファイルをダブルクリックして、インストーラを実行します。見慣れたWindowsのインストーラですので、ここでは詳しくは書きません。画面の指示に従ってインストールを進めて下さい。PICTはコマンドライン・ツールですが、インストーラがパスも通してくれますので少し得した気分です。

PICTの実行:

PICTはテストケース生成ツールですので、言語が特定されるとか、テスト用のプログラムを作らなければいけない訳ではないのですが、実際の現場を想像し易いように(?)簡単なダミー画面を作ってみました。

no image

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        /*
         * 初期設定
         */
        public Form1()
        {
            InitializeComponent();

            this.Text = "鉄男じゃないよ!";

            // 山手線
            comboBox1.Items.Add("東京");      // 0
            comboBox1.Items.Add("有楽町");     // 1
            comboBox1.Items.Add("新橋");      // 2
            comboBox1.Items.Add("浜松町");     // 3
            comboBox1.Items.Add("田町");      // 4
            comboBox1.Items.Add("品川");      // 5
            comboBox1.Items.Add("大崎");      // 6
            comboBox1.Items.Add("五反田");     // 7
            comboBox1.Items.Add("目黒");      // 8
            comboBox1.Items.Add("恵比寿");     // 9
            comboBox1.Items.Add("渋谷");      // 10
            comboBox1.Items.Add("原宿");      // 11
            comboBox1.Items.Add("代々木");     // 12
            comboBox1.Items.Add("新宿");      // 13
            comboBox1.Items.Add("新大久保");    // 14
            comboBox1.Items.Add("目白");      // 15
            comboBox1.Items.Add("池袋");      // 16
            comboBox1.Items.Add("大塚");      // 17
            comboBox1.Items.Add("巣鴨");      // 18
            comboBox1.Items.Add("駒込");      // 19
            comboBox1.Items.Add("田端");      // 20
            comboBox1.Items.Add("西日暮里");    // 21
            comboBox1.Items.Add("日暮里");     // 22
            comboBox1.Items.Add("鶯谷");      // 23
            comboBox1.Items.Add("上野");      // 24
            comboBox1.Items.Add("御徒町");     // 25
            comboBox1.Items.Add("秋葉原");     // 26
            comboBox1.Items.Add("神田");      // 27


            comboBox1.SelectedIndex = 16;
        }

        /*
         * 
         */
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (((ComboBox)sender).SelectedIndex) {
                case 16:
                    // 接続線1
                    comboBox2.Items.Add("池袋");      // 0
                    comboBox2.Items.Add("北池袋");     // 1
                    comboBox2.Items.Add("下板橋");     // 2
                    comboBox2.Items.Add("大山");      // 3
                    comboBox2.Items.Add("中板橋");     // 4
                    comboBox2.Items.Add("常盤台");     // 5
                    comboBox2.Items.Add("上板橋");     // 6
                    comboBox2.Items.Add("東武練馬");    // 7
                    comboBox2.Items.Add("下赤塚");     // 8
                    comboBox2.Items.Add("成増");      // 9
                    comboBox2.Items.Add("和光市");     // 10

                    // 接続線2
                    comboBox3.Items.Add("池袋");      // 0
                    comboBox3.Items.Add("要町");      // 1
                    comboBox3.Items.Add("千川");      // 2
                    comboBox3.Items.Add("小竹向原");    // 3
                    comboBox3.Items.Add("氷川台");     // 4
                    comboBox3.Items.Add("平和台");     // 5
                    comboBox3.Items.Add("地下鉄赤塚");   // 6
                    comboBox3.Items.Add("地下鉄成増");   // 7
                    comboBox3.Items.Add("和光市");     // 8

                    // 接続線3
                    comboBox4.Items.Add("池袋");      // 0
                    comboBox4.Items.Add("新大塚");     // 1
                    comboBox4.Items.Add("茗荷谷");     // 2
                    comboBox4.Items.Add("後楽園");     // 3
                    comboBox4.Items.Add("本郷三丁目");   // 4
                    comboBox4.Items.Add("御茶ノ水");    // 5
                    comboBox4.Items.Add("淡路町");     // 6
                    comboBox4.Items.Add("大手町");     // 7
                    comboBox4.Items.Add("東京");      // 8
                    break;
            }
        }
    }
}

図とソースコードを見れば分かる通りコンボボックスが4つ配置されており、それぞれcomboBox1には28個、comboBox2には11個、comboBox3には9個、comboBox4にも9個のパラメタ値があります。全てのパラメタ値の組み合わせは、28×11×9×9=24,984通りにもなってしまいます。こんなに膨大な量のテストケースでは、現実のプロジェクトに於いては実施は不可能であると言えます。

では、PICTを実行してみましょう。先ず、パラメタのリストを作成します。 パラメタ名とパラメタ値は、テキストファイルに記述します。パラメタ名とパラメタ値を「:(コロン)」で区切り、パラメタ値同士を「,(カンマ)」で区切ります。注意しなければならないのが、今回のように日本語を使う場合にはEUCで記述する必要があることです。

no image

コマンドプロンプトを開いて、PICTを実行します。生成されるテストケースが多い場合には、リダイレクションでファイルに出力すると便利です。

DOS> pict test.txt > result.txt

直ぐに、結果が返ってきます。

no image

結果が多いので全てを表示することはできませんが、308通りのテストケースが生成されました。これならば、なんとか頑張れば・・・という量かも知れません。

本当に大丈夫なの?:

24,948通りのテストケースが308通りに劇的に圧縮されましたが、理論に基づいて削減されたとはいえ手放しでは喜べません。厳密なところで「本当に大丈夫なの?」という不安が浮かんできます。
PICTの作者の同僚で、QICTというツールを作成したMicrosoftのJames McCaffreyさんの記事(http://msdn.microsoft.com/ja-jp/magazine/ee819137.aspx)には、「ペアワイズ・テストは、確率的な要因を備えた組み合わせ手法」と書かれています。「確率的」であるということは即ち、理論的に確率の低いテストケースは省かれているということですか。
では、どのような組み合わせが省かれるのでしょうか?何が生成されて何が省かれるのか、それが分かれば何らかの手を打てる筈です。その検証は次回からにしたいと思います。

それでは。