組み合わせテストケース生成ツール 「PictMaster」 とソフトウェアテストの話題 -61ページ目

制御パステストはあまり実施されていない?

これまで制御パステストにPairwise法(All-Pairs法)を適用する方法についてかなりの回数、記事に取り上げてきましたが、こうした検討は系統立てて行う必要があり、このブログでは扱いきれない大きなテーマであるため、今後は取り上げないことにしました。

ある程度まとまった成果が得られたらこのブログで紹介する予定です。現在、このような検討を行なう時間があまり取れないため、成果の紹介にはしばらく時間がかかりそうです。


話題は変わりますが、「制御パステストというテスト技法はあまり使われていないように思われます。ネットで検索してみたのですが、制御パステストについて詳しく説明したWebページは見当たりませんでした。いくつかのメーカから制御パステストを「自動的」に実施するツールが紹介されていましたが、どうも実用的に使える、という感じがしません。実際に制御パステストを実施しようとすると、全てのパスをカバーする各種変数の値や入力パラメータの値を適切に決める必要がありますが、こうしたことを紹介されているツールで「自動的」に行なうことには無理があると感じました。


多くのツールでは制御パステストの自動実行機能よりもカバレッジの測定機能をアピールしているようです。あとは価格の問題もあるでしょう。
こうしたツールを使ったことがないので的外れな意見かもしれませんが。


もれのない制御パステスト(ここでは条件網羅とします)を実施するためには以下の条件をすべて満足する必要があると考えています。これはカバレッジを100%にするということを前提としています。


(1)すべての制御パスが網羅されていること。
(2)網羅された制御パスには実際のプログラムでは実行不可能なパスが含まれていないこと。
(3)すべての制御パスを通るように変数の値、入力パラメータの値、などの組み合わせ(テストデータのセット)が決定されていること。
(4)テストデータの各セットは、基本的に同値分割、境界値分析を行なって適切な値のセットであること。


以上の条件をすべて満たすことは通常は非常に困難だと思われます。まず(1)の制御パスをすべて網羅することが難しいでしょう。コンポーネントのステップ数が100行くらいになると、手作業ですべての条件分岐(真と偽の両方を通る)制御パスを網羅することは困難だと思います。そこにループが入れ子になっていたりするともう手に負えなくなるだろうと思います。フローチャートを作っても無理そうです。


続いて(2)ですが、プログラム構造と変数がとりうる値の組み合わせの結果によっては、通れない制御パスが存在することがあります。この制御パスは除外する必要があります。

すべての制御パスを通る変数の組み合わせなどのテストデータのセットを決めることが困難な場合があります。


(3)の場合、網羅した個々の制御パスが通るパス上で変数の値を更新しているケースでは、そのあとの条件文の分岐条件によっては、通れないパスとなっている場合があり得ます。つまりどのように変数の値を組み合わせても通れない制御パスができてしまうのです。この場合は、個々の制御パスの条件文の組み合わせを修正し、通れるパスに訂正する必要があります。


最後に(4)ですが、ほとんどの場合、個々のコンポーネントの性質により、同値分割、境界値分析の方法が異なり、各コンポーネントに最適なテストデータのセットを用意することは、どこまでの深さのテストを実施したいかによって変わってきます。つまり、データセットの決め方でテストの粒度(テストの細かさ)が変わるのです。


さて、仮にこうした条件をすべて満たしたとした場合、従来の方法でバグを検出できるのは、特定の1つのパラメータが特定の値の場合に起きるバグのみです。2つのパラメータがともに特定の値の場合をとるときに起きるバグを見つけることができません。Pairwise法による制御パステストでは、こうしたケースのバグも検出することができます。その代わりテストケース数は若干増えることになります。


以上の各条件を満たす制御パスとテストデータのセットを自動的に決定してくれるツールは存在しないように思われます。所々で人手で手を加えるという方法でなら可能なツールがあるかもしれません。


ではPictMasterなど、Pairwise法を採用したツールでかつ制約の指定に制約表を用いるツールではどうでしょうか。


(1)については制約表を使用することで比較的簡単にすべての制御パスを網羅することができます。この場合は2つのパラメータの組み合わせを網羅したものになります。

(2)については、プログラム構造と変数の関係で通れないパスは制約表で指定することで除外することができます。

(3)については、最初に最低限必要と思われるテストデータのセットを作成し、各セットが抽出した制御パスのどれを通るかを調べます。その結果、1度も通っていないパスがあれば、そのパスを通るテストデータを追加することになります。最も手のかかる部分がこの作業で、テストデータによってどのパスを通るかを決定するには時間がかかります。
(4)については、モデルを作成するときに、どのようなパラメータと値を採用するかで決めることができます。


Pairwise法による制御パステストは、従来の条件網羅の制御パステストよりもカバレッジが高い制御パステストです。そのためテストケース数がより多くなるため、すべての場合にPairwise法による制御パステストを実施するということは現実的ではないと思われます。

Pairwise法による制御パステストがふさわしいのは、特に重要なコンポーネント、バグが見逃された場合、リスクの大きなコンポーネントなどに限定して適用することが現実的だと思われます。

制御パステストのテストケースをAll-Pairs(Pairwise)法で作成する(実例編) 最終

制御パステストの条件網羅のテストケースをAll-Pair法を用いて作成する方法を実際のプログラムを例に説明します。

今回の説明で取り上げるプログラムは、All-PairIIのプロシージャである「重み付け値展開」です。このプログラムは値の並び欄で値の右にカッコ( )で囲まれた数字を記述することにより、値の数がその数字の値だけ並ぶようにします。
例えば、a, b(5), c と記述すると、このプログラムで値 b が5個並んだ以下の文字列に変換されます。

 b,b,b,b,b,a,c

プロシージャ「重み付け値展開」のソースリストを以下に示します。

リスト1.「重み付け値展開」のソースリスト
このソースリストからパラメータと値の並びであるモデルを記述します。パラメータ欄には制御パスが変化する条件文などを記述し、値の並び欄にはそれらの条件文などが取うる値、True, false などを記述します。今回はパラメータ名を条件文の名称と10づつの追い番で表現しています。

リスト1のモデルを以下に示します。

表1.モデル
組み合わせテストツール PictMaster と AllPairII を使う-モデル


次にこのモデルをもとに可能な制御パスを制約表で指定します。制約条件の true, false ごとに次の分岐先のパラメータ欄の行の制約表に制約対象として取りうる値 true, fals などを記入します。これを最初のパラメータから順次繰り返します。これはソースリストを見ながら行ないます。

この制約表を以下に示します。

表2.制約表
組み合わせテストツール PictMaster と AllPairII を使う-制約表1

組み合わせテストツール PictMaster と AllPairII を使う-制約表2

組み合わせテストツール PictMaster と AllPairII を使う-制約表3

組み合わせテストツール PictMaster と AllPairII を使う-制約表4


以上のモデルと制約で生成された制御パステスト(条件網羅)のテストケースを以下に示します。

表3.テストケース
組み合わせテストツール PictMaster と AllPairII を使う-テストケース

このテストケースで右端の set number については後で説明します。
次にこのプロシージャに与えるテストデータと期待する結果を決めます。今回の場合は以下のテストデータとしました。

表4.テストデータと期待する結果
組み合わせテストツール PictMaster と AllPairII を使う-テストデータ

次にこのテストデータでテストケースのすべてをカバーしているかを確認します。これは個々のテストデータがどのテストケースの制御パスを通るかを確認することです。表3のテストケースの右端の set number がそのテストケースの制御パスを通るテストデータのセット番号を表しています。
制御パスが複雑な場合は、テストデータが通る制御パスを見つけるのが難しい場合があり得ますが、その場合はテストケースにExcelのフィルタを使って該当するテストケースを見つけ出す方法もあります。
今回のプロシージャではループを含んでいるため、1つのテストデータで2つ以上のテストケースを実行することになります。

当初考えたテストデータでは実行することのないテストケースが出ることがあります。この場合は2つの可能性があります。1つはテストデータが不足している場合。この場合はそのテストケースを通るテストデータを追加します。もう1つの可能性はテストケースが制御パスとして矛盾している場合です。この場合はそのテストケースが生成されないように制約表に制約を追加します。

今回の記事を書くためにテストデータを決めた際、セット番号8のテストデータが不足していたので後で追加しました。また通れないテストケースのあることが分かり、後で制約を3つ追加しています。こうしてテストデータとテストケースを完全なものにします

このプロシージャでは他のプロシージャを呼び出していますが、これは使用できない場合はスタブに置き換えることになります。

今回のモデルと制約の場合、生成エンジンにJennyを使用すると「組み合わせに現れない値がある」というエラーメッセージが表示されますが、これはJennyのバグと思われます。実際に生成してみる場合は生成エンジンにPICTを使用してください。またはPictMasterで生成してください。今回のテストケースの生成にはマシンに Intel Xeon 2.8GHz を使用して1回の生成で1分19秒かかりました。また最少テストケース生成を行なっても生成数は15個で一定でした。Jennyはバグのために使用できません。一方、PICTはパラメータ数が多くなると生成時間が極端に長くなる傾向があります。この点はPICTによる制御パステストのテストケース生成に限界があることを意味しています。

今回の方法は制御パステストにAll-Pair法を適用する際の方法の1つに過ぎません。対象とするプログラムの性質によってまた違った方法がふさわしい場合もあり得ると考えられます。

制御パステストにAll-Pair法を適用する際の方法について検討することは、このブログの範疇を超える大きなテーマだと考えられます。したがってこれらのテーマを扱うのは今回をもって一応の終わりとします。

ループを含むコンポーネントの制御パステストと経路網羅のテストケース

いろいろなプログラムを対象として制御パステストにAll-Pair法を適用してきました。今回はループを含むプログラムですが、このプログラムは日経BP社から発行されている「初めて学ぶソフトウェアのテスト技法」という書籍の143ページめに例題として掲載されているものです。

書籍では「基礎パステスト」技法の説明に用いられています。基礎パステストとは、ソースリストから制御フローグラフを作成し、それをもとにサイクロマチック数という値を求め、その値だけの基礎パスを選択し、それをテストケースとする技法です。基礎パステストは命令網羅と条件網羅をカバーします。ただし、プログラムがループを含まない部分のみに適用可能な技法です。

以下にそのプログラム(JAVA)のソースリストを示します。命令部分は s1, s2, s3, ... という形に形式化されています。条件文の部分も c1, c2, c3, ... に形式化されています。

組み合わせテストツール PictMaster と AllPairII を使う-ソースリスト

図1.ループを含むプログラムのソースリスト

このソースリストの制御フローグラフを以下に示します。この図で青色の部分は制御フロー(制御パス)が変化する部分です。
組み合わせテストツール PictMaster と AllPairII を使う-制御フローグラフ
図2.ループを含むコンポーネントの制御フローグラフ


PictMasterでソースリストをもとにモデルと制約表を記入します。制御フローグラフは不要です。記入したモデルと制約表を以下に示します。制御パスが変化する部分をパラメータとして採用します。制約表の記入は例によって制約条件が次の制約対象になる、という方法で記入しますが、結果として同じ意味の制約ができることがあります。以下の制約表ではそのような同じ意味の制約を1つにまとめて制約の数を少なくしてあります。


組み合わせテストツール PictMaster と AllPairII を使う-モデルと制約表

組み合わせテストツール PictMaster と AllPairII を使う-制約表その2

図3.モデルと制約表


このモデルと制約表で生成したテストケースを以下に示します。

表1.生成したテストケース
組み合わせテストツール PictMaster と AllPairII を使う-テストケース

テストケースでは、ループを完了した場合のほかにループの途中でのパスのテストケースも含まれています。サイクロマチック数を用いる「基礎パステスト」技法では、ループ途中のテストケースは扱えないためループを完了した場合の制御フローだけのテストケースとなります。書籍ではテストケース数が8となっています。一方、PictMasterで生成したテストケースはループ途中のケースも含んでいるため、12個のテストケースとなっています。このうちループが完了したテストケースは7個となっています。

ループ途中のテストケースは、当該テストケースの条件となる時点でプログラムをブレークし、意図どおりの動作となっているかを確認することになります。

All-Pair法では条件網羅のほかに経路網羅のテストケースも生成することができます。このやり方は極めて簡単で、条件網羅を生成するようにしたツールの環境設定で、組み合わせるパラメータ数にモデルに記述されているパラメータの数と同じ数を設定し、生成するだけです。

表2.経路網羅のテストケース
組み合わせテストツール PictMaster と AllPairII を使う-経路網羅テストケース

今回のプログラムでの経路網羅のテストケース数は42個となりました。まだテストケース数はそれほど多くはありませんが、一般的に経路網羅のテストケース数はパラメータ数が多いと膨大なテストケース数となりますので注意が必要です。

JaSST'09 東京で発表しました。

JaSST'09 東京で、「オープンソースの組み合わせテストツールの開発」というテーマで発表を行ないました。

発表時間が30分という短い中に、PictMasterとAllPairIIがどのようなテスト分野に適用できるかを中心に実例を上げて説明したのですが、説明が駆け足になってしまい分かりにくかったと思います。

最も一般的な総合テストへの適用事例、状態の往復がある状態遷移図から状態遷移のテストケースを生成する適用事例、そして制御パステストのテストケースを生成する事例についても説明しました。

今回のプレゼンテーションファイルは、後日PDFファイルとしてJaSSTのサイトに掲載されますので、そちらをゆっくり閲覧していただければ理解の助けになるのではと思います。もちろんJaSSTに参加されなかった方にもそのPDFファイルを見れば大体理解していただけるように詳しく書いたつもりです。

それでは、また。

制御構造が直列型の場合の制御パステスト プログラム内で値が変化する場合の値の決め方

前回に続いて今回は制御構造が直列型の制御パステストについて取り上げます。

直列型では、プログラム内で値が変化することによって制御パスが変化するという副作用を持つ場合があります。今回はこうした副作用を持つ場合に、条件網羅をカバーする値の初期値を決める方法を紹介します。

一般的に言って制御パステストを実施する際に、すべての経路を網羅する適切な初期値を決めることが難しい場合があります。プログラム内で制御パスの違いにより値が異なる変化を起こすためです。

それでは副作用を持つ直列型の例として以下のソースリストを示します。このプログラムでは値Aと値Bは0以上の整数とします。

リスト1.直列型制御構造のソースリストの例

組み合わせテストツール PictMaster と AllPairII を使う-ソースリスト

このソースリストのフローチャートを以下に示します。
組み合わせテストツール PictMaster と AllPairII を使う-フローチャート

図1.直列型制御構造のフローチャートの例

このフローチャートを見ると、制御パスに影響を与える値が何回も変化しています。これはどの制御パスから通ってきたかによって次に通る制御パスが異なることを意味します。

こうした副作用を持つケースでは、これまでの、制約対象が次の制約条件になる、という従来の制約表の記入方法だけでは対処できません。モデルと従来の方法だけで記入した制約表を示します。

組み合わせテストツール PictMaster と AllPairII を使う-モデルと制約表

図2.直列型制御構造のモデルと制約表の例

このモデルと制約表で生成したテストケースを示します。このときの生成エンジンはPICTである必要があります。Jennyでは生成エンジンの仕様上の制限事項でエラーとなります。

表1.従来の方法でのテストケース
組み合わせテストツール PictMaster と AllPairII を使う-修正前の生成結果

このテストケースを見ると、No.3,4で値Aまたは値Bが条件を満たすことができません
そこで条件を満たすように以下の制約を追加します。

組み合わせテストツール PictMaster と AllPairII を使う-制約表2

図3.追加した制約

この制約を追加して改めて生成した結果を以下に示します。

表2.副作用を考慮したテストケース
組み合わせテストツール PictMaster と AllPairII を使う-修正後の生成結果

表の右側の黄色のAとBの値は、その行のテストケースを実施する際に採用する値です。この値は当該テストケースの条件と命令文を考慮することでおのずと決まります。

今回のプログラムのテストケースは4個となりました。数が少ないのでフローチャートをなぞってみて実際にすべての条件文の真と偽の両方を通ることを確認できます。

通常の条件網羅とは異なり、All-Pair法によるテストケースのため、2つの要因の組み合わせによる障害を検出することができます。