EXCEL上で動作するテスト設計支援ツールPICT-PAPPを使ってPairwise組み合わせテストを設計する手順

[PICT-PAPP(Pairwise Independent Combinatorial Tool - Pre-And-Post Processor)](https://github.com/sho1884/PICT-PAPP)の紹介や、それをつくることに至った背景については[別稿に記載](https://qiita.com/sho1884/items/a46bb9bb5aca490f90f5)しました。
本稿では早速、組み合わせテストを設計する手順の説明に入ります。（因子・水準の洗い出しがほぼ終わったあたりからの手順になります。その手前の準備で何をすべきかについては[良質な記事が他にあります](https://www.facebook.com/permalink.php?story_fbid=904650266323412&id=666101650178276&__xts__[0]=68.ARBqKZb_u8-G7mNg1YycsDJqspZak4iK5spohehsxxqT-FbjJzH9Pz1OYN--gTfLjLK2QAcDrQhfVn6jF5_-MveUCzfXOJJ_YsC6Syxu_CCsM20YBfzJ8q-PIqB4JJFeFAP21xroQAzw4ccvO5m1hRXzZiVjiUGGoVnitiVVakoQ2lFXpxX5PHoulUpwaTPDLInpfzV6XK46RiNuGI_GLyB-74wMCekAMK9qC6UwjZmSy676lIyRsxlKWh4P3ZChWc70T-nd6ecm0xTmcsKWoSvscZLN-6Il7ULVVQmXN5FWyfcFeI17FQVUqIgdFHQRTMRUWCMiwAkht0yyq90&__tn__=-R)ので、そちらを参考にしてください。）

# ツール環境の準備
[PICT-PAPP(Pairwise Independent Combinatorial Tool - Pre-And-Post Processor)](https://github.com/sho1884/PICT-PAPP)は、外部ツール[CIT-BACH](http://www-ise4.ist.osaka-u.ac.jp/~t-tutiya/CIT/)と[PICT](https://github.com/Microsoft/pict)への入力ファイルを生成し、指定した外部ツールであるCIT-BACHもしくはPICTを実行します。EXCELのVBAで実装されています。外部ツールは、本ツールが生成したファイルを入力として処理を実行し、結果をやはりファイルに出力します。本ツールはその結果ファイルを読み込んでシートに取り込みます。

これらのファイルが作業用フォルダに置かれることになります。作業用フォルダに設定したフォルダ内のファイルは上書きされたりするので、消えては困るファイルなどが存在するような場所は避けて適切に設定してください。新たに専用のフォルダを作成して頂けると良いと思います。また、本ツールは「外部ツールによる結果の中に出現していない組み合わせが、禁則指定されたもののみであることを確認するためのAlloyソースを生成する」機能もあり、このソースも同じ作業フォルダの中に出力されます。

少なくともCIT-BACHあるいはPICTのどちらかをインストールして、〔処理の指示＆設定〕シートの「**CIT-BACHパス設定**」ボタンを押してcit-bach.jarの場所を設定、または「**PICTパス設定**」ボタンを押してpict.exeの場所を設定します。作業用のフォルダを作成し、〔処理の指示＆設定〕シートの「**作業パス設定**」ボタンを押して、そのフォルダの場所を設定します。
そして、〔処理の指示＆設定〕シートの「**実行Toolの選択**」で実行したい方のツールを選択してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/4e5a78e9-966b-f384-c7c5-6d2cd327e088.png)

- CIT-BACHは次の場所から入手できます。
[http://www-ise4.ist.osaka-u.ac.jp/~t-tutiya/CIT/](http://www-ise4.ist.osaka-u.ac.jp/~t-tutiya/CIT/)
- PICTは次の場所からダウンロードできます。
[http://download.microsoft.com/download/f/5/5/f55484df-8494-48fa-8dbd-8c6f76cc014b/pict33.msi](http://download.microsoft.com/download/f/5/5/f55484df-8494-48fa-8dbd-8c6f76cc014b/pict33.msi)

【注意】基本的に本ツールはシートの名前を頼りにその内容を判断しますので、シート名を不用意に変更しないでください。
【繰り返し作業をする場合】過去に生成したシートが残っていると、シート名が衝突して実行に失敗します。繰り返し作業をする場合には、それらのシートを削除するか、シート名を変えるなどの対処をしてから開始してください。

# 因子・水準の入力
因子と水準の情報を「因子・水準」シートに入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/acdf6a5d-988f-dcc7-9f2b-eab6cf3f23dd.png)


必要に応じて「**Step0) MASK状態を水準として全ての因子に加えます**」ボタンを押して、各因子の水準としてMASK状態を一律に追加します。必要が無ければこのStep0は飛ばします。
【補足説明】この処理は、MASK状態を水準に入れ忘れることがないように用意されています。
MASK状態とは、他の因子の水準の選び方などのシステム状態により、例えばユーザインタフェースが非表示になってしまったりすることで、外部から触れない(設定できない)、無効となっている状態のことです。(原因結果グラフ技法を実践している方であれば、その技法の中でお馴染みのMASK制約に対応することだと理解して頂ければ良いと思います。)
そのような状態が無いならば、制約記述(禁則設定)が面倒になるだけなので、水準に加えるべきではありません。
MASK状態となることがある因子だけに忘れずに一つの水準として分かり易い表現で加えておけば良いだけです。
しかし、このことは忘れられがちなので、まずはこのStep0で全部に一律に加えてしまい、各因子毎に調査して確認し、不要であれば削除する、という手順を踏みたい場合のために用意してあります。

# 総当たり表の自動生成
〔処理の指示＆設定〕シートで「**Step1) 因子・水準 → 総当たり表の生成**」ボタンを押して、総当たり表を自動生成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/ecca94e8-35b5-3452-309a-ceb862570a9e.png)

【注意】この処理は自由度(およそ全因子の水準数の総和)が大きくなるとそれなりに処理時間がかってしまいます。

# 禁則関係を見付ける
自動生成された「総当たり表」シートを開き、禁則関係を見付けます。まずこの時点では、水準の情報は具体的なイメージを持つための参考程度に見るに留め、縦と横の因子と因子の間で禁則関係がありそうなものに印をつけます。(禁則関係がありそうな因子と因子が交差する範囲のセルに？または?を入力したりすると良いでしょう。背景色が赤、あるいは黄に変化します。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/402a604d-4f9d-31e6-e77b-c07faddc335e.png)

禁則関係がさらに別の禁則関係に繋がったり、2つよりも多い因子が関係しそうだとしても、この時点ではあまり深追いせず、まずは見落としが無いことの方に注力してください。
対角線で線対象になるはずです。右上で考えて、左下で確認したりすると良いでしょう。

# 禁則情報の精査
上記の手順で「禁則関係がありそうだ」と見つけた2因子間について、今度は縦横の組み合わせについて水準レベルまで精査して禁則になっている組み合わせを特定していきます。禁則ならばその組み合わせのセルに×(「ばつ」と入力すると変換候補に出てきます。環境依存文字に似た記号がありますが、それではないので注意してください。)をセルに書き込んでください。×を書き込むと、デフォルトの設定のままであればそのセルがピンク色に変わると思います。禁則ではないセルに、先の手順で既に？または?を入力してある場合には空に戻してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/5448dd2b-da7d-5958-af34-4a8e13ed4cfe.png)

対角線で線対象になるはずです。右上で考えて、左下で確認したりすると良いでしょう。
禁則関係を精査している過程で、多項間の禁則関係を見付けた時には、以下の手順で多項間禁則表を使ってその禁則関係を定義します。（多項間の禁則関係が無ければStep1'を実行する必要はありません。）
〔処理の指示＆設定〕シートで「**Step1') 多項禁則マトリクス生成**」ボタンを押して、条件因子と被制約因子を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/a61a19f2-42a0-64cd-c142-3f6063721002.png)

多項間禁則表のシートが生成されます。この表の各マスは総当たり表と同じように振舞いますので、禁則となるセルに同じように×を入力します。多項間禁則表は複数枚生成できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/989c41c4-1f8e-ca90-14e7-b07672d4205b.png)

次の禁則の制約式を生成する処理では、シートの名前に「多項間禁則表」が含まれるシート全てが対象となり処理されます。（逆に言えば、「多項間禁則表」が含まれない名前に変更してしまえば制約式生成の対象にはなりません。）

# 制約式自動生成
〔処理の指示＆設定〕シートで「**Step2) 総当たり表、多項間禁則マトリクスの禁則 → 制約式自動生成**」ボタンを押して、外部Tool入力用の制約式を自動生成し「制約記述」シートの「自動生成制約」セルに出力します。このセルを直接書き換えることはしないでください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/844ab14c-7ff3-034a-5dd5-72c925d5175c.png)

もしも、総当たり表で指定した禁則関係が対角線で線対象になっていない場合、該当するセルの背景色が赤く塗りつぶされるので、確認して修正してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/c1397df7-f936-3b41-04c8-db18bb86a766.png)

**【注意】Step2だけを何度やり直しても問題は起きないので、必ず修正して線対象になるようにしてください。そうなっていないと、その後の処理結果は正しくなりません。**

# 必要に応じて自由記述による制約表現を加える
総当たり表や多項間禁則表の形式以外で表現したい制約は、「制約記述」シートの「自由記述制約」セルに直接記述します。特に何もなければ空欄のままで構いません。
制約式の表記法は各ツールの規則に従っていれば良いです。しかし、最後の手順でAlloyのソースを自動生成したい場合は、PICTの方で、そのルールの中でもさらに次のような形式を守って禁則を記述してください。
    IF [因子1] = ""因子1の水準"" AND [因子2] = ""因子2の水準"" THEN [因子3] <> ""因子3の水準"";
上記の例は3つの因子の場合ですが、4つ以上の場合も同様で、ANDで結合される項目が増えていく形になります。
それ以外の形式の記述ではAlloyソースの生成は正しく処理されません。また、CIT-BACHの方の自由記述はAlloyソースの生成時には完全に無視されますので、注意してください。

# 外部ツールを実行
〔処理の指示＆設定〕シートで「**Step3) Tool実行 → 「ツールの生成結果」シートへ読み込み**」ボタンを押して、ツールを実行します。「ツールの生成結果」シートが生成され、外部ツールが生成した組み合わせリストが読み込まれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/5331f9da-7b99-4b6d-0ff3-42b73c988487.png)

もしもこの結果に修正を加えたい場合は、「ツールの生成結果」シートを複製して、シート名を「テストケース」に変更し、「テストケース」シートの方を修正すると良いでしょう。以降の処理では、「ツールの生成結果」シートと「テストケース」シートの両方が存在する場合、「テストケース」シートの方が優先して処理の対象になります。もちろん、「因子・水準」シートに存在しない水準名を記載してしまうなど、整合しない修正を行ってしまった場合、その後の処理は正しく行われなくなってしまいます。

# 総当たり表へのマッピングを実行
〔処理の指示＆設定〕シートで「**Step4) ツールの生成結果または(編集済み)テストケースシートから分析実行**」ボタンを押すと、「IDマッピング済み総当たり表」シートが生成されます。これは、総当たり表と同じ情報を含み、さらに次の情報が付加されます。

- 対角線より右上の各セルには、「テストケース」シートあるいは「ツールの生成結果」シートの何タプル(行)にその組み合わせが出現したか、その回数を表示します。
- 対角線より左下の各セルには、実際にその組み合わせが、「テストケース」シートあるいは「ツールの生成結果」シートのどのIDのテストケース(行)に出現しているかを表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/1b2a56da-1e2e-e77a-e2df-b46d06c80486.png)

ここで、禁則として指定されていない組み合わせなのに、どのIDのテストケース(行)にも出現していない組み合わせがあった場合、そのセルの値は?となり、背景色は黄色に塗りつぶされます。
また、2因子組合せの数や網羅率を示す「網羅率」シートが生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/bd41887c-45fd-ce32-635c-3da3a7de677b.png)

【注意】この処理は自由度(およそ全因子の水準数の総和)が大きくなると処理に多大な時間がかかるようになります。
例えば、250因子で各因子の水準数が4である場合を考えてみましょう。
250因子から2因子を選ぶ組み合わせの数は以下の通りです。

```math
{}_{250} \mathrm{C}_2=\frac{250 \times 249}{2}=31125
```

いま、外部ツールが80行のタプルを生成したとしましょう。(禁則が少なければ実際そのぐらいになります。)
そうすると、その中に存在する2因子間の水準の組み合わせ(水準のペア)の数は以下の通りとなります。

```math
{}_{250} \mathrm{C}_2 \times 80=2490000
```

このそれぞれが、総当たり表の対角線の片側に存在するマス目(ほぼ(250 × 4 )^2 / 2=500000)の何処に振り分けられるのかを調査していく処理になるので、これはそれなりに時間がかかることは避けられません。とはいえ、VBAは時間掛かり過ぎ、とも思ってしまいますが、、、

# 間接禁則の確認
PICTについて、「禁則（制約として禁止した組み合わせ）以外の2因子の組み合わせについて、全てが必ず出現するとは限らない、実は(制約式が少し複雑になってくると)必ずしもそうではないケースがある」との情報もあります。（私自身は実務の中で取り扱った設計データについて、直交表によるものと比較するためにPICT生成した際に、そのようなケースに出会ったことがあったようにも記憶しているのですが、現時点でそれを再現するようなサンプルを再構成することができていません。どちらとも確認ができていない状況です。）
PICT-PAPPで「IDマッピング済み総当たり表」シートに黄色に塗りつぶされたセルが出てきてしまった場合、それは禁則設定した制約式に誤りがあったのか、式はあっているがそこから常に導かれることになる2因子間の禁則(間接禁則)を見落としたのか、あるいは単にPICTがその組み合わせを生成しなかっただけなのか、それを確かめる必要が出てきます。（禁則が確実に実装されているかのテストが必要なので。）ここでもまたツールの力を借りたいという場合、例えばAlloyが有効に使えます。
そこで、この問題の確認をするためのAlloyのソースを自動生成する機能が本ツールには備わっています。

- Alloy Analyzerは以下の次の場所からダウンロードできます。
 [http://alloytools.org/download.html](http://alloytools.org/download.html)

〔処理の指示＆設定〕シートで「**Step5) 禁則を確認するAlloyソースの自動生成**」ボタンを押すと、「制約記述」シートの「Alloyによる検証用表現」セルにそのソースを出力します。同時に作業フォルダにも「ペアが存在しなくて良いことを検証するalloyソース.als」というファイル名で出力され、Alloyが起動されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/73638649-423f-57a3-72ee-ae87b0802980.png)

Alloyで実行ボタンを押して、インスタンスが一つも見つからなければ黄色に塗りつぶされた組み合わせは禁則なので、その組み合わせは出力されていなくて正解ということになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/d4823b01-1391-5aa7-d949-a16b1afe4bc5.png)

つまり総当たり表の黄色のセルは間接禁則だということになり、禁則を総当たり表において定義する際に認識し損なったものということになります。このAlloyの結果はそのことを証明するわけではありませんが、その確度が格段に高いことを示してはくれます。これとは反対に、もしもインスタンスが見つかる場合、そのインスタンスには禁則ではないのにToolが生成し損なった組み合わせが現れていることになります。
ところで、HAYST法が示唆する通り、2因子の網羅性について、著しくバランスを欠いているといった欠陥などが無ければ、80％程度で十分な効果が得られるといえます。ですから、ここで神経質に禁則を除いた100％網羅に、そんなに執着する必要は実はありません。むしろ禁則確認テストのために意義ある情報となるでしょう。(実はこのAlloyのソースはもう少し違った目的にも使えるのですが、そのことについては別途どこかで説明したいと思っています。)

# 水準を水準値に具体化してテストデータを生成する
本ツールPICT-PAPPにおいては、ここまで水準といえば水準名を使用することを前提としています。（一方、例えばHAYST法ツールは水準値を入れることを前提としており、それが推奨されています。）どういうことかを具体例で示しますと、3つの水準を「1, 5, 10」とそれぞれ水準値で表現するのではなく、「1～10の範囲の整数の下限, 1～10の範囲の整数の境界値以外, 1～10の範囲の整数の上限」といったように、設計している段階ではできるだけ意味が分かり易い名前を使った方が良いだろう、との考えで、そうすることを想定しているということです。
さてそうすると、今度は最後に水準名を水準値に具体化する作業が残ることになります。本ツールにはこの作業を支援する機能が付いています。
〔処理の指示＆設定〕シートで「**Step6) 因子・水準・水準値設定表の生成**」ボタンを押すと、「因子・水準・水準値」シートが生成されます。水準値の列には水準(名)と同じ値が複製されています。水準値の列を必要に応じて具体値に置き換えてください。（この機能は因子・水準が入力済みであればいつでも実行可能なので、初期のうちに実行して、備考欄に同値分割の考え方などを記録しておくのも良いと思います。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/0d87d6a3-0ba1-eb4a-8aeb-2e459cb6dab7.png)

次に、〔処理の指示＆設定〕シートで「**Step7) 水準を水準値に置換 → テストデータ生成**」ボタンを押すと、「ツールの生成結果」シートまたは「テストケース」シート（両方が存在する場合は「テストケース」シートの方が優先して処理の対象になります）が「テストデータ」シートとして複製されます。ただし、この「テストデータ」シートの方は水準(名)が「因子・水準・水準値」シートの情報に従って水準値に置き換えられたものとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/12bbaeba-5f87-dd0d-425e-89308cab61d5.png)

（「テストデータ」シートの各水準値のセルには、実際には具体値ではなく「因子・水準・水準値」シートの対応する水準値セルを参照するような式が入っています。あとから「因子・水準・水準値」シートの方を変更すると「テストデータ」シートの方も動的に変更されることになりますので、注意してください。）

# おまけ
〔処理の指示＆設定〕シートの「**おまけ) 因子・水準 →全組み合わせ生成**」ボタンについてです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/c0ae2d2d-cef1-70b2-1a5b-088a9f2eb8f7.png)

言うまでもないと思いますが、実務的な因子・水準が入力されたそのままの状態では天文学的な行数の生成を指示してしまうことになります。お気を付けください。