以下,本実施の形態について,図を用いて説明する。
図1は,本実施の形態によるテスト対象プログラムの例を示す図である。
一般に,ソフトウェア開発などでは,開発されたプログラムについて,バグがないかなどを確認するテストが行われる。以下では,テストの対象となるプログラムをテスト対象プログラム200と呼ぶ。図1に示すテスト対象プログラム200は,プログラミング言語のCOBOLで記述されたプログラムの一例である。
図1に示すテスト対象プログラムでは,「発注量」,「規定値」,「発注量上限」,「発注量下限」の4つの変数が宣言されている。変数「規定値」,「発注量上限」,「発注量下限」は固定値が設定された内部定数であり,変数「発注量」は入力変数である。
プログラミング言語には,COBOLやPL/1などのように,桁の概念があるプログラミング言語が存在する。桁の概念があるCOBOLなどで記述されたプログラム内で変数を使う際には,その変数の桁数を宣言する必要がある。例えば,図1に示すテスト対象プログラム200でも,変数の宣言時に,その桁数の宣言も行われている。
図1に示すテスト対象プログラム200において,例えば,変数「発注量」の宣言における「9(3)」の記述は,変数「発注量」が3桁の数値型であることを示す。また,変数「規定値」の宣言における「X(3)」の記述は,変数「規定値」が3桁の文字列型であることを示す。また,変数「発注量上限」の宣言における「9(5)」の記述は,変数「発注量上限」が5桁の数値型であることを示す。また,変数「発注量下限」の宣言における「X(5)」の記述は,変数「発注量下限」が5桁の文字列型であることを示す。なお,本実施の形態では,文字列の長さも桁と表すものとする。
図1に示すテスト対象プログラム200において,変数「規定値」,「発注量上限」,「発注量下限」には,固定値が設定されている。変数「規定値」には,文字列“009”が固定値として設定されている。変数「発注量上限」には,数値“00099”が固定値として設定されている。変数「発注量下限」には,文字列“001 ”が固定値として設定されている。
図2は,本実施の形態による処理パスを説明する図である。
図2には,図1に示すテスト対象プログラム200について,特に条件判定による処理の分岐に着目した処理の流れが記述されている。例えば,図1に示すテスト対象プログラム200には,図2に示す3つの分岐[1]〜[3]がある。
分岐[1]:(発注量=規定値)についてのtrue/false
分岐[2]:(発注量>発注量上限)についてのtrue/false
分岐[3]:(発注量<発注量下限)についてのtrue/false
これらの分岐[1]〜[3]におけるtrue/false の判定結果によって,図1に示すテスト対象プログラム200が実行する処理の流れが,複数に分かれることになる。
プログラムが実行する処理の流れは,処理パスと呼ばれる。通常,プログラムには,条件判定による処理の分岐があり,その分岐での判定結果に応じた複数の処理パスが存在する。図1に示すテスト対象プログラム200には,図2に示すように,4つの処理パス(1)〜(4)が存在する。
処理パス(1):分岐[1]でtrueとなる処理パス
処理パス(2):分岐[1]でfalse となり,分岐[2]でtrueとなる処理パス
処理パス(3):分岐[1]でfalse となり,分岐[2]でfalse となり,分岐[3]でtrueとなる処理パス
処理パス(4):分岐[1]でfalse となり,分岐[2]でfalse となり,分岐[3]でfalse となる処理パス
このように,図1に示すテスト対象プログラム200には,分岐[1]〜[3]におけるtrue/false の結果に応じた処理パス(1)〜(4)が存在する。
図1に示すテスト対象プログラム200のテストでは,例えば,テスト対象プログラム200がそれぞれの処理パス(1)〜(4)を正常に実行できるかを調べるテストが行われる。テストの実施者は,それぞれの処理パス(1)〜(4)に対するテストごとに,テスト対象プログラム200に目的とする処理パスを実行させるための変数への入力値を用意する必要がある。以下では,テストにおいてテスト対象プログラム200の変数に入力する入力値を,テストデータとも呼ぶ。
図1に示すテスト対象プログラム200のテストでは,変数「発注量」に値を入力してテストが行われる。このとき,テストの実施者は,テスト対象プログラム200にテストの目的とする処理パスを実行させるための変数「発注量」の値を,テストデータとして用意する。以下では,図1に示すテスト対象プログラム200のテストに用いるテストデータを生成する例を説明する。
図2に示す各処理パス(1)〜(4)についてそれぞれテストするためのテストデータは,それぞれの処理パス(1)〜(4)のパス条件を解くことにより得られる。パス条件は,テスト対象プログラムにテストの目的とする処理パスを実行させる条件である。例えば,パス条件は,目的とする処理パスを実行させるために各分岐の判定で変数が満たすべき条件となる。テストの目的とする処理パスのパス条件を満たす変数の値が,そのテストにおけるテストデータとなる。
例えば,テスト実施者が処理パス(4)をテストしたい場合,分岐[1]の判定条件(発注量=規定値)がfalse となり,かつ分岐[2]の判定条件(発注量>発注量上限)がfalse となり,かつ分岐[3]の判定条件(発注量<発注量下限)がfalse となるテストデータを用意する。したがって,これらの条件の論理積「NOT(発注量=規定値),かつNOT(発注量>発注量上限),かつNOT(発注量<発注量下限)」が,処理パス(4)をテストするためにテストデータが満たすべき条件を示すパス条件となる。
テスト対象プログラムに処理パス(1)〜(4)を実行させるためのパス条件(1)〜(4)は,それぞれ次の通りとなる。
パス条件(1):(発注量=規定値)
パス条件(2):NOT(発注量=規定値),かつ(発注量>発注量上限)
パス条件(3):NOT(発注量=規定値),かつNOT(発注量>発注量上限),かつ(発注量<発注量下限)
パス条件(4):NOT(発注量=規定値),かつNOT(発注量>発注量上限),かつNOT(発注量<発注量下限)
このようなパス条件の導出方法としては,例えば,仕様書に基づいて人手で導出する方法や,プログラムのシンボリック実行により導出する方法などがある。
それぞれの処理パスをテストするためのテストデータは,上記で示したパス条件を解くことで得られる。しかし,パス条件を人手で解くことは容易ではない。特に,多数の分岐を通過する処理パスを実行させる場合,パス条件は長く複雑なものとなり,人手で解くのは難しい。
制約ソルバを用いて,与えられたパス条件を満たすテストデータを算出する技術がある。制約ソルバは,ある変数の満たすべき条件の入力に対して,その変数に入り得る値の実例を1つ返すツールである。制約ソルバに関する技術について記載された文献としては,例えば参考文献1が挙げられる。
〔参考文献1〕
R.E. Bryant ,Daniel Kroening ,Ofer Strichman,“Decision Procedures: An Algorithmic Point of View (Texts in Theoretical Computer Science. An EATCS Series)”,Springer,2008/7/7
参考文献1には,制約ソルバ(SAT(Satisfiability)ソルバ,SMT(Satisfiable Modulo Theories )ソルバ)に関する技術についての説明が記載されている。ここでは,制約ソルバについての詳細な説明は省略する。
また,制約ソルバを用いてテストデータを生成する技術としては,例えば参考文献2や参考文献3に記載された技術などがある。
〔参考文献2〕
特開2011−85967号公報
〔参考文献3〕
Tao Xie ,Darko Marinov ,Wolfram Schulte ,David Notkin,“Symstra: A Framework for Generating Object-Oriented Unit Tests using Symbolic Execution ”,Proc. of TACAS 2005 ,Tools and Algorithms for the Construction and Analysis of Systems ,LNCS,vol 3340,pages 365-381 ,April 2005.
参考文献2や参考文献3には,SMTソルバを用いてテストデータの生成を行う技術の例が記載されている。
テストデータの生成において,制約ソルバにパス条件を入力する際には,パス条件を制約ソルバが解釈できる記述に置き換える必要がある。以下では,制約ソルバが解釈できる記述を,制約記述と呼ぶ。
図3は,本実施の形態による処理パス(1)のテストデータを求める制約記述の例を示す図である。
図3に示す制約記述210は,テスト対象プログラム200に処理パス(1)を実行させるテストデータを得るためのパス条件(1)が,制約ソルバが解釈する記述に置き換えられた制約記述の一例である。
図3に示す制約記述210において,<変数の宣言>部分には,処理パス(1)のパス条件(1)に関係する2つの変数「発注量」,「規定値」について,その定義と値の取り得る範囲の制約が記述されている。図3に示す制約記述210では,変数は桁数を配列長とする配列で定義されている。図3に示す制約記述210における変数の定義と値の取り得る範囲の制約についての詳細は,後述する。
図3に示す制約記述210において,<固定値の制約>部分には,テスト対象プログラム200で固定値が設定された変数「規定値」を,その固定値“009”で制約する記述がなされている。
制約ソルバでは整数と整数の配列しか扱えないため,制約記述では,文字列を整数で表現する必要がある。制約記述において文字列を整数で表現する技術としては,例えば参考文献4に記載された技術などがある。
〔参考文献4〕
Nikolaj Bjorner ,Nikolai Tillmann and Andrei Voronkov,“Path Feasibility Analysis for String-Manipulating Programs”,Proc. of TACAS 2009 ,Tools and Algorithms for the Construction and Analysis of Systems ,LNCS,vol 5505,pages 307-321 ,March 2009.
参考文献4には,制約ソルバ上で文字列を文字コードとして表現する技術についての説明が記載されている。
本実施の形態では,文字列型の変数をアスキーコードの配列に置き換えることで,文字列型の変数を制約ソルバで扱えるようにする。なお,本実施の形態では,テスト対象プログラム200で文字列型の変数と数値型の変数とを比較している場合に,数値型の変数をアスキーコードの配列で表現された文字列型の変数と比較するために,数値型の変数もアスキーコードの配列に置き換えるものとする。
テスト対象プログラム200において,変数「規定値」は3桁の文字列型の変数である。そのため,図3に示す制約記述210では,変数「規定値」は,配列長が3であるアスキーコードの配列に置き換えられる。“0”はアスキーコードの48番であり,“9”はアスキーコードの57番であるので,変数「規定値」の配列に固定値“009”を制約する記述は,図3の制約記述210における<固定値の制約>部分に示す通りとなる。
図3に示す制約記述210において,<満たすべき条件の制約>部分には,パス条件(1)における変数が満たすべき条件(発注量=規定値)の制約が記述されている。
ここで,図3に示す制約記述210では,テスト対象プログラム200において3桁の数値型で宣言された変数「発注量」が,長さ3の配列型であることを示すIntegerLen3 で定義されている。また,テスト対象プログラム200において3桁の文字列型で宣言された変数「規定値」が,長さ3の配列型であることを示すStringLen3で定義されている。
また,図3に示す制約記述210において,長さ3の配列で定義された変数「発注量」の値域は,関数IsIntegerLen3 によって,0〜9の数字に対応するアスキーコードの範囲内に収まるように制約される。また,図3に示す制約記述210において,長さ3の配列で定義された変数「規定値」の値域は,関数IsStringLen3によって,空白,0〜9,A〜Z,a〜z等の文字に対応するアスキーコードの範囲内に収まるように制約される。
図4は,本実施の形態による数値型/文字列型の変数の配列を定義する記述の例を示す図である。
図4(A)に示す数値型の記述220は,3桁の数値型の変数の配列を定義する記述の例を示す。図4(A)に示す数値型の記述220において,IsIntegerLen3 に関する記述では,IntegerLen3 で定義される配列長3の配列が,それぞれ0〜9の数字に対応するアスキーコードの範囲(48番〜57番)になるように定義されている。他の桁数の数値型の変数の配列を定義する記述についても,同様である。
図4(B)に示す文字列型の記述230は,3桁の文字列型の変数の配列を定義する記述の例を示す。図4(B)に示す文字列型の記述230において,IsStringLen3に関する記述では,StringLen3で定義される配列長3の配列が,それぞれ空白,0〜9,A〜Z,a〜z等の文字に対応するアスキーコードの範囲(32番,48〜57番,65〜122番)になるように定義されている。他の桁数の文字列型の変数の配列を定義する記述についても,同様である。
このような桁数ごと型ごとに変数の配列の定義する記述のデータを,制約ソルバに入力させておく。この状態で,図3に示す制約記述210のデータを入力すると,制約ソルバは,パス条件(1)を満たす充足解となる変数「発注量」の値を1つ出力する。
図5は,本実施の形態による制約ソルバの実行結果の例を示す図である。
図5に示す実行結果240は,図3に示す制約記述210を制約ソルバに入力した際に出力される充足解の一例である。図5に示す制約ソルバの実行結果240では,変数「発注量」の配列の要素ごとに,アスキーコードで結果が示されている。アスキーコード48番は“0”,アスキーコード57番は“9”であるので,図5に示す実行結果240から得られる変数「発注量」の値は“009”となる。
このように,パス条件(1)について記述した制約記述210を制約ソルバに入力すると,パス条件(1)を満たす変数「発注量」の値として,制約ソルバから“009”が返される。ここで得られた変数「発注量」の値“009”が,図1に示すテスト対象プログラム200に処理パス(1)を実行させるテストを行う際に,変数「発注量」に入力するテストデータとなる。テストの実施者は,変数「発注量」にテストデータ“009”を入力して図1に示すテスト対象プログラム200を実行することで,処理パス(1)についてのテストを行うことができる。
図6は,本実施の形態による処理パス(4)のテストデータを求める制約記述の例を示す図である。
上記のように,処理パス(4)をテストするためのテストデータを生成する場合のパス条件(4)は,「NOT(発注量=規定値),かつNOT(発注量>発注量上限),かつNOT(発注量<発注量下限)」である。パス条件(4)を,前述した処理パス(1)のテストデータを生成するときと同様のやり方で,そのまま制約ソルバに入力できる記述に変換すると,例えば図6に示す制約記述215のようになる。
なお,図6に示す制約記述215において,IntegerLen5 は,配列長を5とする数値型の変数の配列の定義を示し,StringLen5は,配列長を5とする文字列型の変数の配列の定義を示すものとする。また,IsIntegerLen5 は,配列長を5とする数値型の変数の配列の値域が所定のアスキーコードの範囲内に収まるように制約する関数を示し,IsStringLen5は,配列長を5とする文字列型の変数の配列の値域が所定のアスキーコードの範囲内に収まるように制約する関数を示すものとする。
図6に示す制約記述215において,変数「発注量」の配列は配列長が3であり,変数「発注量上限」の配列と変数「発注量下限」の配列の配列長は5である。すなわち,図6に示す制約記述215では,<満たすべき条件の制約>部分において,(not(> 発注量 発注量上限))の制約と(not(< 発注量 発注量下限) )の制約とで,配列長が異なる配列同士を制約することになる。制約ソルバでは,配列長が異なる配列同士を制約することができないため,図6に示す制約記述215の実行結果はエラーとなってしまう。
このような問題が発生する原因は,パス条件をそのまま制約記述に変換するやり方では,COBOLの転記ルールを想定した制約の記述ができないことにある。転記は,分岐における条件判定時に,一時的に変数の値を別の値に書き写すことである。
COBOLのプログラムでは,数値型の変数に対する「桁」を記述するようになっている。また,COBOLのプログラムでは,桁数が異なる変数間の比較条件や,数値型の変数と文字列型の変数との間の比較条件を記述することができる。COBOLのプログラムの実行時には,桁数や型が異なる変数の値をそのまま比較することはできないため,転記が行われる。
COBOLにおける転記のルールは,例えば,次の通りとなる。
・転記ルール#1:数値と文字列を比較する際には,数値を文字列に転記し,文字列比較を行う。
・転記ルール#2:数値比較の実行時に,桁数の異なる変数間で比較を行う場合,桁数が少ない方の変数の値を右詰めにし,桁数が等しくなるまで左側に“0”を詰める。
・転記ルール#3:文字列比較の実行時に,桁数の異なる変数間で比較を行う場合,桁数が少ない方の変数の値を左詰めにし,桁数が等しくなるまで右側に空白を詰める。
図7は,COBOLにおける転記ルールを説明する図である。
図7(A)は,桁数が同じ数値型の変数と文字列型の変数とを比較する場合の転記の例を示す。図7(B)は,桁数が異なる数値型の変数同士を比較する場合の転記の例を示す。図7(C)は,桁数が異なる数値型の変数と文字列型の変数とを比較する場合の転記の例を示す。なお,図7において,「発注量」の値の“?”は,値が固定値ではないことを示している。また,文字列の値における“¥”は,空白を表すものとする。
図7(A)には,図1に示すテスト対象プログラム200の分岐[1]において,変数「発注量」と変数「規定値」とを比較する場合の例が示されている。テスト対象プログラム200において,変数「発注量」は3桁の数値型であり,変数「規定値」は3桁の文字列型である。上記の転記ルール#1から,図7(A)に示すように,3桁の数値である変数「発注量」の値が3桁の文字列の値に転記され,3桁の文字列である変数「規定値」の値との文字列比較が行われる。
図7(B)には,図1に示すテスト対象プログラム200の分岐[2]において,変数「発注量」と変数「発注量上限」とを比較する場合の例が示されている。テスト対象プログラム200において,変数「発注量」は3桁の数値型であり,変数「発注量上限」は5桁の数値型である。
上記の転記ルール#2から,図7(B)に示すように,3桁の数値である変数「発注量」の値が5桁の数値に転記される。このとき,先頭の2桁に“0”が詰められる。転記によって5桁の数値となった変数「発注量」の値と,5桁の数値である変数「発注量上限」の値との数値比較が行われる。
図7(C)には,図1に示すテスト対象プログラム200の分岐[3]において,変数「発注量」と変数「発注量下限」とを比較する場合の例が示されている。テスト対象プログラム200において,変数「発注量」は3桁の数値型であり,変数「発注量下限」は5桁の文字列型である。
上記の転記ルール#1と転記ルール#3とから,図7(C)に示すように,3桁の数値である変数「発注量」の値が5桁の文字列に転記される。このとき,末尾の2桁に空白が詰められる。転記によって5桁の文字列となった変数「発注量」の値と,5桁の文字列である変数「発注量下限」の値との文字列比較が行われる。
制約記述に記述できるのは変数の宣言と制約のみであり,分岐の条件に応じて変数の値を書き換えることはできない。そのため,COBOLプログラム実行時に起こる転記を制約として,制約記述に対してそのまま記述することはできない。桁の概念を持つCOBOLなどのプログラミング言語については,転記ルールを想定した制約を記述することができないため,すべてのパス条件を正しく制約記述に置き換えることは困難である。
より具体的には,例えば,
1)数値型の変数で「桁」を宣言するプログラム言語で記述されたプログラムにおける処理パスのパス条件であり,
2)パス条件中に数値型の変数Aと,数値型の変数B,文字列型の変数Cが存在し,
3)数値型の変数Aの桁数より,数値型の変数Bの桁数が大きく,
4)数値型の変数Aの桁数より,文字列型の変数Cの桁数が大きく,
5)分岐の条件に,変数Aと変数Bとを比較する比較条件が含まれており,
6)分岐の条件に,変数Aと変数Cとを比較する比較条件が含まれている
場合に,そのパス条件を正しく制約記述に置き換えることは困難である。
以下では,桁の概念を持つプログラミング言語で記述されたプログラムについて,制約ソルバを用いてテストデータを生成する際に,パス条件のデータから正しい制約記述のデータを自動的に生成する本実施の形態の技術について,説明する。
図8は,本実施の形態によるテストデータ生成装置の構成例を示す図である。
図8に示すテストデータ生成装置100は,テスト対象プログラム200に特定の処理パスを実行させるための変数の値を自動生成する。なお,図8に示すテストデータ生成装置100において,実線は主に制御関係を示し,破線は主にデータ関係を示す。
テストデータ生成装置100は,パス条件情報記憶部110,制約記述生成部120,制約設定情報記憶部130,制約記述情報記憶部140,制約ソルバ実行部150,充足解情報記憶部160,結果処理部170,テスト情報記憶部180を備える。
パス条件情報記憶部110は,パス条件情報を記憶する記憶部である。パス条件情報は,テスト対象プログラム200に特定の処理パスを実行させる条件を示すパス条件の情報である。パス条件情報記憶部110に記憶されるパス条件の情報は,あらかじめテスト対象プログラム200から,人手で,またはコンピュータによる自動処理で用意される。
制約記述生成部120は,制約ソルバに入力する制約記述のデータを,パス条件情報記憶部110に記憶されたパス条件情報から自動で生成する。
このとき,制約記述生成部120は,制約記述のデータを自動生成する際の上記の転記ルール#2,転記ルール#3への対処として,転記で桁の補完が行われる変数について,配列長を増加した変数の配列を宣言するように設定を行う。転記の対象となる変数が文字列型の変数であれば,変数の配列の末尾から転記によって増加する桁数分の要素に,空白の値を設定する。また,転記の対象となる変数が数値型の変数であれば,変数の配列の先頭から転記によって増加する桁数分の要素に,“0”の値を設定する。COBOLで記述されたプログラムの実行時における転記による値の引き伸ばしは,その比較条件の実行において臨時に行われるものであり,他の処理に影響を与えない。制約記述においても,転記への対処が転記が行われない条件文に影響することを防ぐために,桁数を補完した分の配列の要素に,あらかじめ意味のない値,すなわち空白や“0”を設定しておく。
また,制約記述生成部120は,制約記述のデータを自動生成する際の上記の転記ルール#1への対処として,値が文字列に転記され得る数値型の変数があれば,該数値型の変数の配列に加えて,さらに該数値型の変数に対応する比較用の変数の配列を宣言するように設定を行う。例えば,図1に示すテスト対象プログラム200における変数「発注量」のように,数値への転記と文字列への転記とが起こる変数については,桁数を補完する位置が先頭になったり,末尾になったりするので,どこからどこまでが本来の変数の桁であるのかが判別困難になる。制約記述において,数値型の変数に対応する文字列との比較用の変数の配列を別に用意することで,数値型の変数の配列に対する桁の補完先を先頭に限定することが可能となり,常に変数の配列の末尾から本来の桁が始まると判別できるようになる。数値型の変数の値を文字列に転記する条件に対しては,数値型の変数に対応する比較用の変数の配列を用いた制約を行うようにする。
制約設定情報記憶部130は,制約設定情報を記憶する記憶部である。制約設定情報は,制約記述で宣言する変数の配列や,変数の配列を制約する設定が記録される情報である。本実施の形態の制約記述生成部120は,パス条件情報から中間データとなる制約設定情報を生成し,その制約設定情報を自動変換することで制約記述のデータを生成する。
制約記述情報記憶部140は,制約記述生成部120によって自動生成された制約記述のデータを記憶する記憶部である。
制約ソルバ実行部150は,自動生成された制約記述のデータを入力として,制約ソルバを実行する。
充足解情報記憶部160は,充足解情報を記憶する記憶部である。充足解情報は,制約ソルバが出力する制約ソルバの実行結果のデータである。制約ソルバの実行結果は,例えば図5の実行結果240に示すように,変数の配列の要素ごとの文字コードとして得られる。
結果処理部170は,充足解情報記憶部160に記憶された充足解情報から,実際にテストに用いることができる変数の値のデータを生成する。本実施の形態で得られる充足解情報には,テストで用いる変数のデータとして不要なデータも含まれる場合がある。結果処理部170は,充足解情報から不要なデータを削除した最終的な結果のデータを生成する。
テスト情報記憶部180は,結果処理部170により得られた結果のデータを記憶する記憶部である。テスト情報記憶部180に記憶される結果データには,テストを行う際に入力する変数の値すなわちテストデータが含まれる。
制約記述生成部120は,変数宣言情報生成部121,変数制約情報生成部122,比較用変数追加部123,比較対象変更部124,桁補完部125,補完桁制約設定部126,比較用変数制約設定部127,変換部128を備える。
変数宣言情報生成部121,比較用変数追加部123,桁補完部125は,制約記述で宣言する変数の配列を設定する変数設定機能部(図示省略)となる。変数設定機能部は,パス条件情報記憶部110に記憶されたパス条件の情報に基づいて,変数の桁数を配列長とする変数の配列を設定する。このとき,変数設定機能部は,数値型の変数については,該数値型の変数に対応する比較用の変数の配列をさらに設定する。また,変数設定機能部は,異なる桁数の変数を比較する条件における桁数が少ない方の変数については,桁数が多い方の変数の桁数に合わせて配列長を増加した変数の配列を設定する。
より具体的には,変数宣言情報生成部121は,パス条件に存在する各変数について,変数の桁数を配列長とする変数の配列を設定する。本実施の形態では,変数宣言情報生成部121は,変数の配列の設定を,制約設定情報記憶部130に記憶する制約設定情報に記録する。
比較用変数追加部123は,パス条件に存在する数値型の変数について,該数値型の変数に対応する比較用の変数の配列をさらに追加で設定する。比較用変数追加部123は,比較用の変数の配列の設定を,制約設定情報記憶部130の制約設定情報に追加で記録する。制約記述において,比較用の変数の配列は,文字列型の変数の配列と同様に扱われる。
桁補完部125は,パス条件に異なる桁数の変数を比較する条件が存在する場合に,その条件で比較が行われる変数で桁数が少ない方の変数については,桁数が多い方の変数の桁数に合わせて配列長を増加する設定を行う。桁補完部125による設定は,制約設定情報記憶部130の制約設定情報に反映される。
変数制約情報生成部122,比較対象変更部124は,変数の配列の制約を設定する制約設定機能部(図示省略)となる。制約設定機能部は,パス条件情報記憶部110に記憶されたパス条件の情報に基づいて,変数が満たすべき条件に応じた変数の配列の制約を設定する。このとき,制約設定機能部は,数値型の変数と文字列型の変数との比較を行う条件については,該数値型の変数に対応する比較用の変数の配列と該文字列型の変数の配列とを比較する条件の制約を設定する。
より具体的には,変数制約情報生成部122は,パス条件における変数が満たすべき条件に応じて,変数の配列の制約を設定する。本実施の形態では,変数制約情報生成部122は,変数の配列の制約の設定を,制約設定情報記憶部130に記憶する制約設定情報に記録する。
比較対象変更部124は,パス条件に数値型の変数と文字列型の変数との比較を行う条件が存在する場合に,その条件に応じた変数の配列の制約について,該数値型の変数の配列を,該数値型の変数に対応する比較用の変数の配列に変更する設定を行う。比較対象変更部124による設定は,制約設定情報記憶部130の制約設定情報に反映される。
補完桁制約設定部126は,配列長を増加した変数の配列について,増加した分の配列の要素に所定の値を設定する。より具体的には,補完桁制約設定部126は,数値型の変数の配列については,先頭から増加した分の要素を所定の値に制約する設定を行う。また,補完桁制約設定部126は,文字列型の変数の配列と比較用の変数の配列については,末尾から増加した分の要素を所定の値に制約する設定を行う。本実施の形態では,補完桁制約設定部126は,増加した分の配列の制約の設定を,制約設定情報記憶部130に記憶する制約設定情報に記録する。
比較用変数制約設定部127は,数値型の変数の配列と,該数値型の変数に対応する比較用の変数の配列との関係を制約する設定を行う。本実施の形態では,比較用変数制約設定部127は,2つの配列間の関係の制約の設定を,制約設定情報記憶部130に記憶する制約設定情報に記録する。
変換部128は,設定された変数の配列および制約から,制約ソルバが解釈する記述データを生成する。より具体的には,変換部128は,制約設定情報記憶部130に記憶された制約設定情報を自動変換することで,制約ソルバが解釈する記述データ,すなわち制約記述のデータを生成する。生成された制約記述のデータは,制約記述情報記憶部140に記憶される。
結果処理部170は,逆変換部171,補完桁削除部172,比較用変数削除部173を備える。
逆変換部171は,充足解情報記憶部160に記憶された充足解情報を自動変換し,結果データを生成する。ここで生成された結果データは,変数の配列の要素ごとの文字コードのデータである充足解情報が,テスト対象プログラム200における変数の値のデータに変換されたデータである。逆変換部171は,得られた結果データを,テスト情報記憶部180に記憶する。
補完桁削除部172は,制約設定情報記憶部130の制約設定情報を参照し,テスト情報記憶部180に記憶された結果データから,配列長を増やした変数について,増加した配列の要素に相当する文字を削除する。より具体的には,補完桁削除部172は,テスト情報記憶部180の結果データにおいて,配列長を増やした数値型の変数については,先頭から増加した分の文字を削除する。また,補完桁削除部172は,テスト情報記憶部180の結果データにおいて,配列長を増やした文字列型の変数については,末尾から増加した分の文字を削除する。
比較用変数削除部173は,制約設定情報記憶部130の制約設定情報を参照し,テスト情報記憶部180に記憶された結果データから,比較用の変数のデータを削除する。
図9は,本実施の形態によるテストデータ生成装置によるテストデータ生成処理フローチャートである。
テストデータ生成装置100の制約記述生成部120において,変数宣言情報生成部121は,変数宣言情報生成処理を実行する(ステップS10)。変数宣言情報生成処理は,パス条件に存在する変数について,制約記述で宣言する変数の配列を設定する処理である。変数宣言情報生成処理の詳細な例については,後述する。
変数制約情報生成部122は,変数制約情報生成処理を実行する(ステップS11)。変数制約情報生成処理は,パス条件に存在する変数が満たすべき条件に応じて,変数の配列の制約を設定する処理である。変数制約情報生成処理の詳細な例については,後述する。
比較用変数追加部123は,比較用変数追加処理を実行する(ステップS12)。比較用変数追加処理は,数値型の変数について,その数値型の変数に対応する比較用の変数の配列を追加で設定する処理である。比較用変数追加処理の詳細な例については,後述する。
比較対象変更部124は,比較対象変更処理を実行する(ステップS13)。比較対象変更処理は,数値型の変数と文字列型の変数とを比較する条件について設定された制約において,数値型の変数の配列を,その数値型の変数に対応する比較用の変数の配列に変更する処理である。比較対象変更処理の詳細な例については,後述する。
桁補完部125は,桁補完処理を実行する(ステップS14)。桁補完処理は,異なる桁数の変数を比較する条件において桁数が少ない方の変数の配列について,桁数が多い方の変数の配列長にあわせて配列を補完する処理である。桁補完処理の詳細な例については,後述する。
補完桁制約設定部126は,補完桁制約設定処理を実行する(ステップS15)。補完桁制約設定処理は,桁補完処理で配列長が増加された変数の配列について,増加した分の配列の要素に所定の値を制約する設定を行う処理である。補完桁制約設定処理の詳細な例については,後述する。
比較用変数制約設定部127は,比較用変数制約設定処理を実行する(ステップS16)。比較用変数制約設定処理は,数値型の変数の配列と,その数値型の変数に対応する比較用の変数の配列との関係を示す制約を設定する処理である。比較用変数制約設定処理の詳細な例については,後述する。
変換部128は,制約設定情報記憶部130の制約設定情報を自動変換することで,制約ソルバが解釈する制約記述のデータを生成する(ステップS17)。制約ソルバ実行部150は,生成された制約記述のデータを入力として,制約ソルバを実行する(ステップS18)。結果処理部170において,逆変換部171は,制約ソルバの実行結果である充足解情報記憶部160の充足解情報を自動変換することで,パス条件を満たす変数の値が記録された結果データを生成する(ステップS19)。
補完桁削除部172は,補完桁削除処理を実行する(ステップS20)。補完桁削除処理は,結果データにおける変数の値から,配列長の増加によって補完された文字を削除する処理である。補完桁削除処理の詳細な例については,後述する。
比較用変数削除部173は,比較用変数削除処理を実行する(ステップS21)。比較用変数削除処理は,結果データに残っている比較用の変数を削除する処理である。比較用変数削除処理の詳細な例については,後述する。
図10は,本実施の形態によるテストデータ生成装置を実現するコンピュータのハードウェア構成例を示す図である。
図8に示す本実施の形態のテストデータ生成装置100を実現するコンピュータ1は,例えば,CPU(Central Processing Unit )2,主記憶となるメモリ3,記憶装置4,通信装置5,媒体読取・書込装置6,入力装置7,出力装置8等を備える。記憶装置4は,例えばHDD(Hard Disk Drive )等の外部記憶装置や,補助記憶装置などである。媒体読取・書込装置6は,例えばCD−R(Compact Disc Recordable )ドライブやDVD−R(Digital Versatile Disc Recordable )ドライブなどである。入力装置7は,例えばキーボード・マウス等の入力機器などである。出力装置8は,例えばディスプレイ等の表示装置などである。
図8に示すテストデータ生成装置100およびテストデータ生成装置100が備える各機能部は,コンピュータ1が備えるCPU2,メモリ3等のハードウェアと,ソフトウェアプログラムとによって実現することが可能である。コンピュータ1が実行可能なプログラムは,記憶装置4に記憶され,その実行時にメモリ3に読み出され,CPU2により実行される。
コンピュータ1は,可搬型記録媒体から直接プログラムを読み取り,そのプログラムに従った処理を実行することもできる。また,コンピュータ1は,サーバコンピュータからプログラムが転送されるごとに,逐次,受け取ったプログラムに従った処理を実行することもできる。さらに,このプログラムは,コンピュータ1で読み取り可能な記録媒体に記録しておくことができる。
以下では,本実施の形態によるテストデータ生成の技術について,より具体的な例を用いて説明を行う。ここでは,図1に示すテスト対象プログラム200に図2に示す処理パス(4)を実行させるためのテストデータを生成する例を説明する。なお,以下で説明する例では,図1に示すテスト対象プログラム200で宣言されている変数を,データ項目とも呼ぶものとする。また,制約記述で宣言する変数を,単に変数と呼ぶものとする。
図11は,本実施の形態によるデータ項目テーブルおよび分岐条件テーブルの例を示す図である。
図11に示すデータ項目テーブル112,分岐条件テーブル114は,パス条件情報記憶部110に記憶された,テスト対象プログラム200に処理パス(4)を実行させるためのパス条件(4)についてのパス条件情報の一例である。
図11(A)に示すデータ項目テーブル112は,パス条件(4)にあるデータ項目についての情報が記録されたデータの一例である。データ項目テーブル112は,データ項目,型,桁数,固定値の情報を持つ。データ項目は,テスト対象プログラム200で宣言されたデータ項目を示す。型は,テスト対象プログラム200において,該当データ項目が数値型で宣言されているか文字列型で宣言されているかを示す。桁数は,テスト対象プログラム200で宣言された,該当データ項目の桁数を示す。固定値は,テスト対象プログラム200において,該当データ項目に定義された固定値を示す。固定値が設定されていないデータ項目については,データ項目テーブル112に固定値の情報がない。
図11(B)に示す分岐条件テーブル114は,テスト対象プログラム200の処理が処理パス(4)の流れとなるように,分岐において満たすべき条件の情報が記録されたデータの一例である。分岐条件テーブルは,第1オペランド,演算子,第2オペランドの情報を持つ。演算子は,分岐において満たすべき条件を示す式の演算子である。第1オペランドは,分岐において満たすべき条件を示す式の左辺を示し,第2オペランドは,分岐において満たすべき条件を示す式の右辺を示す。
上記のパス条件(4)は,「NOT(発注量=規定値),かつNOT(発注量>発注量上限),かつNOT(発注量<発注量下限)」となっている。分岐条件テーブル114は,上記のパス条件(4)のNOT括弧書きを展開した,条件「(発注量NOT=規定値),かつ(発注量<=発注量上限),かつ(発注量>=発注量下限)」に基づいて,生成されている。
図11に示すデータ項目テーブル112,分岐条件テーブル114は,テスト対象プログラム200とパス条件(4)とから,人手により,またはコンピュータを用いた解析によって生成され,パス条件情報記憶部110に格納される。
図12は,本実施の形態による変数宣言データおよび変数制約データの例を示す図である。
図12に示す変数宣言データ132,変数制約データ134は,変数宣言情報生成部121,変数制約情報生成部122により生成され,制約設定情報記憶部130に記憶される制約設定情報の一例である。変数宣言情報生成部121,変数制約情報生成部122は,図11に示すデータ項目テーブル112,分岐条件テーブル114から,図12に示す変数宣言データ132,変数制約データ134を生成する。
図12(A)に示す変数宣言データ132は,制約記述で宣言する変数の配列の設定が記録されたデータの一例である。変数宣言データ132は,データ項目,型,桁数,固定値,変数名,配列長,文字列型変数名の情報を持つ。データ項目,型,桁数,固定値については,図11(A)に示すデータ項目テーブル112のデータ項目,型,桁数,固定値と同様である。変数名は,該当データ項目について,制約記述で宣言する変数の名称である。配列長は,該当変数名の変数の配列について,制約記述で宣言する配列長を示す。文字列型変数名は,該当データ項目が数値型である場合に,文字列の比較用に宣言する変数の名称を示す。
なお,本実施の形態の技術では,数値型のデータ項目については,1つのデータ項目に対して,数値比較用の変数と文字列比較用の変数との2つの変数を割り当てるため,ここではあえてデータ項目の名称を別の変数名に置き換えている。データ項目の名称を,制約記述で宣言するための別の変数名に置き換えずに,そのまま制約記述で使用するようにしてもよい。ただし,この場合でも,後述の数値型のデータ項目について文字列の比較用の変数を別に設定する処理では,文字列の比較用の変数に別の変数名を設定する必要がある。
図12(B)に示す変数制約データ134は,制約記述において,変数の配列が満たすべき条件の制約が設定されたデータの一例である。変数制約データ134は,オペランド#1,開始桁#1,終了桁#1,演算子,オペランド#2,開始桁#2,終了桁#2の情報を持つ。演算子については,図11(B)に示す分岐条件テーブル114の演算子と同様である。オペランド#1,開始桁#1,終了桁#1は,該当制約の式における左辺の情報を示し,オペランド#2,開始桁#2,終了桁#2は,該当制約の式における右辺の情報を示す。左辺(または右辺)が変数の配列を示す場合には,オペランド#1(またはオペランド#2)はその変数名を示し,開始桁#1(または開始桁#2)は開始となる配列要素の番号を示し,終了桁#1(または終了桁#2)は終了となる配列要素の番号を示す。左辺(または右辺)が特定の値を示す場合には,オペランド#1(またはオペランド#2)はその値を示し,開始桁#1(または開始桁#2)と終了桁#1(または終了桁#2)は情報なしとなる。
変数宣言情報生成部121は,変数宣言データ132を生成する。このとき,変数宣言情報生成部121は,変数宣言データ132のデータ項目,型,桁数,固定値については,図11(A)に示すデータ項目テーブル112の各レコードのデータをコピーする。また,変数宣言データ132の各レコードについて,それぞれの型に応じた,制約記述で宣言する一意の変数名を設定する。ここでは,変数宣言情報生成部121は,数値型のデータ項目については“N”に添字を付けた変数名を設定し,文字列型のデータ項目については“S”に添字を付けた変数名を設定する。例えば,各データ項目「発注量」,「規定値」,「発注量下限」,「発注量上限」に,それぞれN1,S1,S2,N2が設定される。また,変数宣言情報生成部121は,変数宣言データ132の各レコードについて,配列長に桁数の値を設定する。ここまでの変数宣言情報生成部121の処理で,変数宣言データ132は,図12(A)に示す通りとなる。
図13は,本実施の形態の変数宣言情報生成部による変数宣言情報生成処理フローチャートである。
図13に示すフローチャートは,図9に示すフローチャートのステップS10に示す変数宣言情報生成処理の一例である。
変数宣言情報生成部121は,データ項目テーブル112から,データ項目を順に1つ選択する(ステップS30)。変数宣言情報生成部121は,選択されたデータ項目についてのデータをデータ項目テーブル112から取得し,変数宣言データ132に記録する(ステップS31)。変数宣言情報生成部121は,変数宣言データ132において,選択されたデータ項目に対して制約記述で宣言する一意の変数名を割り当てる(ステップS32)。変数宣言情報生成部121は,変数宣言データ132において,選択されたデータ項目の配列長に,該データ項目の桁数を設定する(ステップS33)。
変数宣言情報生成部121は,データ項目テーブル112のすべてのデータ項目について処理が終了したかを判定する(ステップS34)。すべてのデータ項目について処理が終了していなければ(ステップS34のNO),変数宣言情報生成部121は,ステップS30の処理に戻って,次のデータ項目の処理に移る。すべてのデータ項目について処理が終了していれば(ステップS34のYES),変数宣言情報生成部121は,処理を終了する。
次に,変数制約情報生成部122は,変数制約データ134を生成する。このとき,変数制約情報生成部122は,図11(B)に示す分岐条件テーブル114の各条件のレコードごとに,対応するレコードを変数制約データ134に生成する。例えば,図11(B)に示す分岐条件テーブル114における1番目の条件について,対応する変数制約データ134のレコードを生成する例を説明する。
図11(B)に示す分岐条件テーブル114の該当条件の第1オペランドには,データ項目「発注量」が記録されている。変数制約情報生成部122は,図12(A)に示す変数宣言データ132から,データ項目「発注量」に対応する変数名N1と配列長“3”を取得する。変数制約情報生成部122は,変数制約データ134の該当レコードにおいて,オペランド#1には取得した変数名N1を設定し,開始桁#1には値“1”を設定し,終了桁#1には取得した配列長“3”を設定する。変数制約データ134の演算子については,変数制約情報生成部122は,図11(B)に示す分岐条件テーブル114の該当条件の演算子“NOT=”をそのまま記録する。図11(B)に示す分岐条件テーブル114の該当条件の第2オペランドには,データ項目「規定値」が記録されている。変数制約情報生成部122は,図12(A)に示す変数宣言データ132から,データ項目「規定値」に対応する変数名S1と配列長“3”を取得する。変数制約情報生成部122は,変数制約データ134の該当レコードにおいて,オペランド#2には取得した変数名S1を設定し,開始桁#2には値“1”を設定し,終了桁#2には取得した配列長“3”を設定する。
変数制約情報生成部122が,このような条件ごとの処理をすべての条件について行うと,変数制約データ134は,図12(B)に示す通りとなる。
図14は,本実施の形態の変数制約情報生成部による変数制約情報生成処理フローチャートである。
図14に示すフローチャートは,図9に示すフローチャートのステップS11に示す変数制約情報生成処理の一例である。
変数制約情報生成部122は,分岐条件テーブル114から,条件を1つ選択する(ステップS40)。変数制約情報生成部122は,変数制約データ134にレコードを生成する(ステップS41)。
変数制約情報生成部122は,変数宣言データ132を参照し,選択された条件の第1オペランドに示すデータ項目に対応する変数名と配列長を取得する(ステップS42)。変数制約情報生成部122は,変数制約データ134の該当レコードのオペランド#1に,取得された変数名を設定する(ステップS43)。変数制約情報生成部122は,変数制約データ134の該当レコードの開始桁#1に値“1”を設定する(ステップS44)。変数制約情報生成部122は,変数制約データ134の該当レコードの終了桁#1に取得された配列長を設定する(ステップS45)。
変数制約情報生成部122は,分岐条件テーブル114の選択された条件の演算子を,変数制約データ134の該当レコードの演算子に設定する(ステップS46)。
変数制約情報生成部122は,変数宣言データ132を参照し,選択された条件の第2オペランドに示すデータ項目に対応する変数名と配列長を取得する(ステップS47)。変数制約情報生成部122は,変数制約データ134の該当レコードのオペランド#2に,取得された変数名を設定する(ステップS48)。変数制約情報生成部122は,変数制約データ134の該当レコードの開始桁#2に値“1”を設定する(ステップS49)。変数制約情報生成部122は,変数制約データ134の該当レコードの終了桁#2に取得された配列長を設定する(ステップS50)。
変数制約情報生成部122は,分岐条件テーブル114のすべての条件について処理が終了したかを判定する(ステップS51)。すべての条件について処理が終了していなければ(ステップS51のNO),変数制約情報生成部122は,ステップS40の処理に戻って,次の条件の処理に移る。すべての条件について処理が終了していれば(ステップS51のYES),変数制約情報生成部122は,処理を終了する。
次に,比較用変数追加部123は,図12(A)に示す変数宣言データ132において,数値型のデータ項目「発注量」,「発注量上限」について,それぞれ新たに比較用の変数S3,S4を定義したレコードを追加する。新たに定義された比較用の変数S3,S4の型は,文字列型とする。桁数,配列数については,元となったレコードのデータが踏襲される。固定値の設定は,行われない。比較用変数追加部123は,元の数値型の変数N1,N2のレコードの文字列型変数名に,それぞれ新たに定義された比較用の変数の変数名S3,S4をポインタとして記録する。
図15は,本実施の形態による変数宣言データの例を示す図である。
図12(A)に示す変数宣言データ132に対して,比較用変数追加部123による比較用の変数の追加設定が行われると,変数宣言データ132は,図15に示す通りとなる。
図16は,本実施の形態の比較用変数追加部による比較用変数追加処理フローチャートである。
図16に示すフローチャートは,図9に示すフローチャートのステップS12に示す比較用変数追加処理の一例である。
比較用変数追加部123は,変数宣言データ132のレコードを1つ選択する(ステップS60)。比較用変数追加部123は,選択されたレコードの型が数値型であるかを判定する(ステップS61)。変数宣言データ132の型において,“数値”は数値型を示している。選択されたレコードの型が数値型でなければ(ステップS61のNO),比較用変数追加部123は,ステップS66の処理に進む。
選択されたレコードの型が数値型であれば(ステップS61のYES),比較用変数追加部123は,選択されたレコードの複製レコードを変数宣言データ132に追加する(ステップS62)。このとき,固定値は複製せずに,複製レコードの固定値は空データにしておくものとする。比較用変数追加部123は,複製レコードの型を文字列型を示す“文字列”に書き換える(ステップS63)。比較用変数追加部123は,複製レコードに新規の変数名を割り当て,書き換える(ステップS64)。比較用変数追加部123は,選択されたレコードの文字列型変数名に,複製レコードの変数名を設定する(ステップS65)。
比較用変数追加部123は,変数宣言データ132のすべてのレコードについて処理が終了したかを判定する(ステップS66)。すべてのレコードについて処理が終了していなければ(ステップS66のNO),比較用変数追加部123は,ステップS60の処理に戻って,次のレコードの処理に移る。すべてのレコードについて処理が終了していれば(ステップS66のYES),比較用変数追加部123は,処理を終了する。
次に,比較対象変更部124は,図12(B)に示す変数制約データ134において,数値型の変数と文字列型の変数とを比較する条件の制約について,数値型の変数を,その変数に対応する比較用の変数に変更する。
例えば,図12(B)に示す変数制約データ134において,1番目のレコードは,数値型の変数N1と文字列型の変数S1とを比較する条件の制約となっている。比較対象変更部124は,図12(B)に示す変数制約データ134の1番目のレコードにおける数値型の変数N1を,その変数N1に対応付けて定義された比較用の変数S3に変更する。図12(B)に示す変数制約データ134の3番目のレコードにおける数値型の変数N1も,同様に比較用の変数S3に変更される。
図17は,本実施の形態による変数制約データの例を示す図である。
図12(B)に示す変数制約データ134に対して,比較対象変更部124による,数値型の変数をその変数に対応する比較用の変数に変更する処理が行われると,変数制約データ134は,図17に示す通りとなる。
図18は,本実施の形態の比較対象変更部による比較対象変更処理フローチャートである。
図18に示すフローチャートは,図9に示すフローチャートのステップS13に示す比較対象変更処理の一例である。
比較対象変更部124は,変数制約データ134のレコードを1つ選択する(ステップS70)。比較対象変更部124は,選択されたレコードのオペランド#1の変数のデータを,変数宣言データ132から取得する(ステップS71)。ここでは,選択されたレコードのオペランド#1の変数を,変数#1と呼ぶものとする。また,比較対象変更部124は,選択されたレコードのオペランド#2の変数のデータを,変数宣言データ132から取得する(ステップS72)。ここでは,選択されたレコードのオペランド#2の変数を,変数#2と呼ぶものとする。
比較対象変更部124は,「変数#1の型が数値型かつ変数#2の型が文字列型」であるかを判定する(ステップS73)。「変数#1の型が数値型かつ変数#2の型が文字列型」であれば(ステップS73のYES),比較対象変更部124は,選択されたレコードのオペランド#1の変数名を,該変数名に対応する文字列型変数名に書き換え(ステップS74),ステップS77の処理に進む。
「変数#1の型が数値型かつ変数#2の型が文字列型」でなければ(ステップS73のNO),比較対象変更部124は,「変数#2の型が数値型かつ変数#1の型が文字列型」であるかを判定する(ステップS75)。「変数#2の型が数値型かつ変数#1の型が文字列型」であれば(ステップS75のYES),比較対象変更部124は,選択されたレコードのオペランド#2の変数名を,該変数名に対応する文字列型変数名に書き換え(ステップS76),ステップS77の処理に進む。
「変数#2の型が数値型かつ変数#1の型が文字列型」でなければ(ステップS75のNO),比較対象変更部124は,そのままステップS77の処理に進む。このケースは,変数#1と変数#2とが互いに同じ型のケースである。
比較対象変更部124は,変数制約データ134のすべてのレコードについて処理が終了したかを判定する(ステップS77)。すべてのレコードについて処理が終了していなければ(ステップS77のNO),比較対象変更部124は,ステップS70の処理に戻って,次のレコードの処理に移る。すべてのレコードについて処理が終了していれば(ステップS77のYES),比較対象変更部124は,処理を終了する。
次に,桁補完部125は,図17に示す変数制約データ134において,配列長が異なる変数同士を比較する条件の制約について,少ない方の変数の配列を,多い方の変数の配列に合わせる。
例えば,図17に示す変数制約データ134において,2番目のレコードと3番目のレコードは,いずれも配列長が“3”の変数と配列長が“5”の変数とを比較する条件の制約となっている。桁補完部125は,図17に示す変数制約データ134において,2番目のレコードで配列長が“3”の変数N1と,3番目のレコードで配列長が“3”の変数S3とについて,図15に示す変数宣言データ132の配列長“3”を“5”に変更する。配列長の変更に合わせて,図17に示す変数制約データ134における,2番目のレコードの終了桁#1と,3番目のレコード終了桁#1とを,該当変数の配列長の増加に合わせて“5”に変更する。図17に示す変数制約データ134において,1番目のレコードにも変数S3があるので,桁補完部125は,1番目のレコードの終了桁#1を,該当変数S3の配列長の増加に合わせて“5”に変更する。
また,変数S3の配列長の変更によって,図17に示す変数制約データ134において,1番目のレコードは,配列長が“3”の変数と配列長が“5”の変数とを比較する条件の制約に変わってしまった。桁補完部125は,配列長が“3”の変数S1について,さらに,図15に示す変数宣言データ132の配列長“3”を“5”に変更する。配列長の変更に合わせて,図17に示す変数制約データ134における1番目のレコードの終了桁#2を,該当変数S1の配列長の増加に合わせて“5”に変更する。また,図15に示す変数宣言データ132において,固定値が設定された変数S1の配列長が“5”に変更されているので,固定値の値を2桁補完して5桁の値に変更する。変数S1は文字列型であるので,固定値の末尾に2桁の空白(¥)を補完する。
図19は,本実施の形態による変数宣言データおよび変数制約データの例を示す図である。
図15に示す変数宣言データ132,図17に示す変数制約データ134に対して,桁補完部125による変数の配列長を変更する処理が行われると,変数宣言データ132,変数制約データ134は,それぞれ図19(A),図19(B)に示す通りとなる。
図20は,本実施の形態の桁補完部による桁補完処理フローチャートである。
図20に示すフローチャートは,図9に示すフローチャートのステップS14に示す桁補完処理の一例である。
桁補完部125は,自身で保持する更新フラグを,偽に設定する(ステップS80)。更新フラグの設定は,ある変数の配列長の変更に連動して,別の変数の配列長の変更が発生するパターンに対応するためである。
桁補完部125は,変数制約データ134のレコードを1つ選択する(ステップS81)。桁補完部125は,選択されたレコードのオペランド#1の変数のデータを,変数宣言データ132から取得する(ステップS82)。ここでは,選択されたレコードのオペランド#1の変数を,変数#1と呼ぶものとする。また,桁補完部125は,選択されたレコードのオペランド#2の変数のデータを,変数宣言データ132から取得する(ステップS83)。ここでは,選択されたレコードのオペランド#2の変数を,変数#2と呼ぶものとする。
桁補完部125は,変数#2の配列長より変数#1の配列長の方が長いかを判定する(ステップS84)。変数#2の配列長より変数#1の配列長の方が長ければ(ステップS84のYES),桁補完部125は,配列長更新処理を実行する(ステップS85)。ここでは,変数#a=変数#1,変数#b=変数#2,終了桁#b=終了桁#2を,配列長更新処理に渡す。配列長更新処理の詳細については,後述する。配列長の更新が行われたので,桁補完部125は,更新フラグを真に設定し(ステップS86),ステップS89の処理に進む。
変数#2の配列長より変数#1の配列長の方が長くなければ(ステップS84のNO),桁補完部125は,変数#1の配列長より変数#2の配列長の方が長いかを判定する(ステップS87)。変数#1の配列長より変数#2の配列長の方が長ければ(ステップS87のYES),桁補完部125は,配列長更新処理を実行する(ステップS88)。ここでは,変数#a=変数#2,変数#b=変数#1,終了桁#b=終了桁#1を,配列長更新処理に渡す。配列長更新処理の詳細については,後述する。配列長の更新が行われたので,桁補完部125は,更新フラグを真に設定し(ステップS86),ステップS89の処理に進む。
変数#1の配列長より変数#2の配列長の方が長くなければ(ステップS87のNO),桁補完部125は,そのままステップS89の処理に進む。このケースは,変数#1の配列長と変数#2の配列長とが同じ配列長のケースである。
桁補完部125は,変数制約データ134のすべてのレコードについて処理が終了したかを判定する(ステップS89)。すべてのレコードについて処理が終了していなければ(ステップS89のNO),桁補完部125は,ステップS81の処理に戻って,次のレコードの処理に移る。
すべてのレコードについて処理が終了していれば(ステップS89のYES),桁補完部125は,更新フラグが真であるかを判定する(ステップS90)。更新フラグが真であれば(ステップS90のYES),桁補完部125は,ステップS80の処理に戻って,再度処理を実行する。更新フラグが真でなければ(ステップS90のNO),桁補完部125は,処理を終了する。
図21は,本実施の形態の桁補完部による配列長更新処理フローチャートである。
桁補完部125は,変数#a,変数#b,終了桁#bの値を取得する(ステップS100)。変数#aは配列長が長い方の変数であり,変数#bは配列長が短い方の変数である。桁補完部125は,変数宣言データ132において,変数#aの配列長で変数#bの配列長を更新する(ステップS101)。
桁補完部125は,変数宣言データ132を参照し,変数#bの型が数値型であるかを判定する(ステップS102)。変数#bの型が数値型であれば(ステップS102のYES),桁補完部125は,変数宣言データ132において,変数#bの固定値の先頭に配列長の増加分だけ“0”を追加する(ステップS103)。変数#bの型が数値型でなければ(ステップS102のNO),すなわち文字列型であれば,桁補完部125は,変数宣言データ132において,変数#bの固定値の末尾に配列長の増加分だけ空白(¥)を追加する(ステップS104)。該当変数に固定値が設定されていない場合には,ステップS102〜ステップS104の処理は不要となる。
桁補完部125は,変数制約データ134におけるステップS81で選択されたレコードの終了桁#bを,変数#bの配列長で更新する(ステップS105)。
次に,補完桁制約設定部126は,図19(B)に示す変数制約データ134に,配列長が増加された変数について,その増加数分の配列の要素に所定の値を制約する設定を追加する。例えば,補完桁制約設定部126は,図19(B)に示す変数制約データ134に,配列長が2つ増加された数値型の変数N1について,その変数の配列の先頭から2つ分の要素を“0”に制約する追加設定を行う。また,補完桁制約設定部126は,図19(B)に示す変数制約データ134に,配列長が2つ増加された文字列型の変数S1,比較用の変数S3について,その変数の配列の末尾から2つ分の要素を空白(¥)に制約する追加設定を行う。
図22は,本実施の形態による変数制約データの例を示す図である。
図19(B)に示す変数制約データ134に対して,補完桁制約設定部126による,配列長が増加された変数についてその増加数分の配列の要素に所定の値を制約する設定の処理が行われると,変数制約データ134は,図22に示す通りとなる。
図23は,本実施の形態の補完桁制約設定部による補完桁制約設定処理フローチャートである。
図23に示すフローチャートは,図9に示すフローチャートのステップS15に示す補完桁制約設定処理の一例である。
補完桁制約設定部126は,変数宣言データ132のレコードを1つ選択する(ステップS110)。補完桁制約設定部126は,選択されたレコードの桁数と配列長とが一致しているかを判定する(ステップS111)。選択されたレコードの桁数と配列長とが一致していれば(ステップS111のYES),ステップS121の処理に進む。変数宣言データ132において,桁数と配列長とが一致しているレコードの変数は,配列長が変更されていない。
選択されたレコードの桁数と配列長とが一致しなければ(ステップS111のNO),補完桁制約設定部126は,変数制約データ134にレコードを追加する(ステップS112)。補完桁制約設定部126は,追加されたレコードのオペランド#1に,選択されたレコードの変数名を設定する(ステップS113)。補完桁制約設定部126は,選択レコードの型が数値型であるかを判定する(ステップS114)。
選択されたレコードの型が数値型であれば(ステップS114のYES),補完桁制約設定部126は,追加されたレコードの開始桁#1に“1”を設定し(ステップS115),終了桁#1に(配列長−桁数)を設定する(ステップS116)。補完桁制約設定部126は,追加されたレコードのオペランド#2に“0”を設定し(ステップS117),ステップS121の処理に進む。
選択されたレコードの型が数値型でなければ(ステップS114のNO),すなわち文字列型であれば,補完桁制約設定部126は,追加されたレコードの開始桁#1に桁数を設定し(ステップS118),終了桁#1に配列長を設定する(ステップS119)。補完桁制約設定部126は,追加されたレコードのオペランド#2に空白を設定し(ステップS120),ステップS121の処理に進む。
補完桁制約設定部126は,変数宣言データ132のすべてのレコードについて処理が終了したかを判定する(ステップS121)。すべてのレコードについて処理が終了していなければ(ステップS121のNO),補完桁制約設定部126は,ステップS110の処理に戻って,次のレコードの処理に移る。すべてのレコードについて処理が終了していれば(ステップS121のYES),補完桁制約設定部126は,処理を終了する。
次に,比較用変数制約設定部127は,比較用の変数S3,S4について,それぞれ元となった数値型の変数N1と,N2との関係を制約する。
例えば,数値型の変数N1と比較用の変数S3とは,型が異なるが元は同じデータ項目「発注量」の変数である。これら2つの変数N1,S3については,配列長の増加により補完された以外の配列の要素で,互いに値を一致させなければならない。これらの変数N1,S3について,比較用変数制約設定部127は,型に応じた補完を考慮して,互いに値を一致させるべき配列の要素の関係の制約を,図22に示す変数制約データ134に設定する。より具体的には,変数N1は配列の先頭から2つめまでの要素が補完されており,変数S3は配列の末尾から2つめまでの要素が補完されているので,変数N1の配列の3番目〜5番目の要素と,変数S3の配列の1番目〜3番目の要素とを対応付ける制約が設定される。
なお,変数N2,S4についても,比較用変数制約設定部127は,図22に示す変数制約データ134に,それら変数N2,S4の関係の制約を設定する。変数N2,S4については,いずれも桁の補完が行われていないので,そのまま対応付ける制約が設定される。
図24は,本実施の形態による変数制約データの例を示す図である。
図22に示す変数制約データ134に対して,比較用変数制約設定部127による数値型の変数と比較用の変数との関係の制約を設定する処理が行われると,変数制約データ134は,図24に示す通りとなる。
図25は,本実施の形態の比較用変数制約設定部による比較用変数制約設定処理フローチャートである。
図25に示すフローチャートは,図9に示すフローチャートのステップS16に示す比較用変数制約設定処理の一例である。
比較用変数制約設定部127は,変数宣言データ132のレコードを1つ選択する(ステップS130)。比較用変数制約設定部127は,選択されたレコードの型が数値型であるかを判定する(ステップS131)。選択されたレコードの型が数値型でなければ(ステップS131のNO),すなわち文字列型であれば,比較用変数制約設定部127は,ステップS139の処理に進む。
選択されたレコードの型が数値型であれば(ステップS131のYES),比較用変数制約設定部127は,変数制約データ134にレコードを追加する(ステップS132)。比較用変数制約設定部127は,追加されたレコードのオペランド#1に,選択されたレコードの変数名を設定する(ステップS133)。比較用変数制約設定部127は,追加されたレコードの開始桁#1に(1+配列長−桁数)を設定し(ステップS134),終了桁#1に配列長を設定する(ステップS135)。
比較用変数制約設定部127は,追加されたレコードのオペランド#2に,選択されたレコードの文字列型変数名を設定する(ステップS136)。比較用変数制約設定部127は,追加されたレコードの開始桁#2に“1”を設定し(ステップS137),終了桁#2に桁数を設定する(ステップS138)。
比較用変数制約設定部127は,変数宣言データ132のすべてのレコードについて処理が終了したかを判定する(ステップS139)。すべてのレコードについて処理が終了していなければ(ステップS139のNO),比較用変数制約設定部127は,ステップS130の処理に戻って,次のレコードの処理に移る。すべてのレコードについて処理が終了していれば(ステップS139のYES),比較用変数制約設定部127は,処理を終了する。
次に変換部128は,図19(A)に示す変数宣言データ132と,図24に示す変数制約データ134とを自動変換することで,パス条件(4)についての制約記述のデータを自動生成する。制約記述は,シンプルな記述のルールに従った規則的な記述となるので,変数の宣言や変数の制約が設定された変数宣言データ132と変数制約データ134とを自動変換して得ることが,容易である。
図26は,本実施の形態による制約記述データの例を示す図である。
図26に示す制約記述データ145は,図19(A)に示す変数宣言データ132と,図24に示す変数制約データ134とを自動変換することにより得られ,制約記述情報記憶部140に記憶される制約記述のデータの一例である。図26において,制約記述データ145の横の数字は,説明の便宜上の理由で付された行番号である。
変換部128は,図26に示す制約記述データ145における<変数の宣言>部分(行番号01〜13)については,図19(A)に示す変数宣言データ132の各レコードにおける変数名,型,配列長の情報を変換して記述する。
例えば,図19(A)に示す変数宣言データ132の1番目のレコードの変数名「N1」,型「数値」,配列長「5」から,図26に示す制約記述データ145の行番号02,03の記述を自動生成することができる。なお,配列長が5の数値型の変数の配列の宣言に用いられるIntegerLen5 ,IsIntegerLen5 については,図4(A)に示す3桁の場合の数値型の記述220と同様の記述があらかじめ用意されている。また,例えば,図19(A)に示す変数宣言データ132の2番目のレコードの変数名「S1」,型「文字列」,配列長「5」から,図26に示す制約記述データ145の行番号04,05の記述を自動生成することができる。なお,配列長が5の文字列型の変数の配列の宣言に用いられるStringLen5,IsStringLen5については,図4(B)に示す3桁の場合の文字列型の記述230と同様の記述があらかじめ用意されている。図19(A)に示す変数宣言データ132における他のレコードについても,同様に記述を自動生成することができる。
変換部128は,図26に示す制約記述データ145における<固定値の制約>部分(行番号15〜21)については,図19(A)に示す変数宣言データ132の固定値が設定されている各レコードにおける変数名,固定値の情報を変換して記述する。
例えば,図19(A)に示す変数宣言データ132の2番目のレコードの変数名「S1」,固定値「009¥¥」(¥は空白)から,図26に示す制約記述データ145の行番号16,17の記述を自動生成することができる。具体的には,変数S1の配列に対して,要素S1[1],S1[2]の値を“0”(ASCIIコード48番)に,要素S1[3]の値を“9”(ASCIIコード57番)に,要素S1[4],S1[5]の値を空白(ASCIIコード32番)に制約する記述が自動生成されている。図19(A)に示す変数宣言データ132において,固定値が設定されている他のレコードについても,同様に記述を自動生成することができる。
変換部128は,図26に示す制約記述データ145における<満たすべき条件の制約>部分(行番号23〜33)については,図24に示す変数制約データ134の各レコードの情報を変換して記述する。
例えば,図24に示す変数制約データ134の1番目のレコードの情報から,図26に示す制約記述データ145の行番号24の記述を自動生成することができる。また,例えば,図24に示す変数制約データ134の4番目のレコードの情報から,図26に示す制約記述データ145の行番号27の記述を自動生成することができる。また,例えば,図24に示す変数制約データ134の7番目のレコードの情報から,図26に示す制約記述データ145の行番号30,31の記述を自動生成することができる。
このように,制約記述生成部120によって,桁の概念を持つプログラミング言語で記述されたプログラムに特定の処理パスを実行させるテストデータを生成する際に,制約ソルバに入力する,該処理パスのパス条件を正しく記述した制約記述のデータを自動生成することが可能となる。
より具体的には,数値型の変数に対応する文字列との比較用の変数をさらに追加設定し,数値型の変数と文字列型の変数とを比較する条件の制約で,数値型の変数の代わりに比較用の変数を用いることにより,制約記述でも,数値から文字列への転記に対応することが可能となる。また,変数の型に応じた桁の補完を設定することで,型や桁数が異なる変数同士の比較条件を,制約記述に反映することが可能となる。
制約記述生成部120によって,パス条件(4)から自動生成された図26に示す制約記述データ145は,制約ソルバ実行部150によって,制約ソルバに入力される。制約ソルバの実行結果は,充足解情報記憶部160に格納される。図26に示す制約記述データ145についての制約ソルバの実行結果は図示していないが,例えば図5に示す実行結果240のような,配列の要素ごとに値が文字コードで表されたデータが得られる。
結果処理部170において,逆変換部171は,制約ソルバの実行結果を変換し,結果データを得る。
図27は,本実施の形態による結果データの例を示す図である。
図27に示す結果データ185は,図26に示す制約記述データ145を制約ソルバに入力した際の実行結果を変換することで得られた結果データの例である。図27に示す結果データ185では,図19(A)に示す変数宣言データ132を用いて,さらに各変数名に対応するデータ項目の情報が付されている。図27に示す結果データ185において,結果値が,パス条件(4)を満たす各変数の値である。
次に,補完桁削除部172は,制約記述を生成する過程で配列長の増加が行われた変数について,図27に示す結果データ185の結果値から,増加された分の桁の文字を削除する。例えば,図19(A)に示す変数宣言データ132において,数値型の変数N1は,配列長が2つ増加されている。変数N1は数値型であるので,補完桁削除部172は,図27に示す結果データ185において,変数N1の結果値“00010”から先頭の2文字“00”を削除する。同様に,図19(A)に示す変数宣言データ132において,文字列型の変数S1は,配列長が2つ増加されている。変数S1は文字列型であるので,補完桁削除部172は,図27に示す結果データ185において,変数S1の結果値“009¥¥”(¥は空白)から末尾の2文字“¥¥”を削除する。
なお,文字列扱いされる比較用の変数S3も配列長が2つ増加されているので,図27に示す結果データ185において,変数S3の結果値“010¥¥”(¥は空白)から末尾の2文字“¥¥”が削除される。ただし,比較用の変数S3は,制約記述生成の過程で定義された変数であるので,本来結果としては不要なデータである。後述の比較用変数削除部173の処理が先に行われる場合には,結果データ185から比較用の変数S3のレコードが削除されているので,補完桁削除部172による処理は行われない。
図28は,本実施の形態による結果データの例を示す図である。
図27に示す結果データ185に対して,補完桁削除部172による制約記述の生成時に増加した分の桁の文字を削除する処理が行われると,結果データ185は,図28に示す通りとなる。
図29は,本実施の形態の補完桁削除部による補完桁削除処理フローチャートである。
図29に示すフローチャートは,図9に示すフローチャートのステップS20に示す補完桁削除処理の一例である。
補完桁削除部172は,結果データ185のレコードを1つ選択する(ステップS140)。補完桁削除部172は,選択されたレコードの変数の情報を,変数宣言データ132から取得する(ステップS141)。
補完桁削除部172は,選択されたレコードの変数の型が数値型であるかを判定する(ステップS142)。選択されたレコードの変数の型が数値型であれば(ステップS142のYES),補完桁削除部172は,選択されたレコードの結果値の先頭から(配列長−桁数)個の文字(“0”)を削除する(ステップS143)。選択されたレコードの変数の型が数値型でなければ(ステップS142のNO),すなわち文字列型であれば,補完桁削除部172は,選択されたレコードの結果値の末尾から(配列長−桁数)個の文字(空白)を削除する(ステップS144)。
補完桁削除部172は,結果データ185のすべてのレコードについて処理が終了したかを判定する(ステップS145)。すべてのレコードについて処理が終了していなければ(ステップS145のNO),補完桁削除部172は,ステップS140の処理に戻って,次のレコードの処理に移る。すべてのレコードについて処理が終了していれば(ステップS145のYES),補完桁削除部172は,処理を終了する。
次に,比較用変数削除部173は,図28に示す結果データ185から,制約記述の生成過程で定義された比較用の変数のレコードを削除する。例えば,図19(A)に示す変数宣言データ132から,変数S3,S4が比較用の変数であることがわかる。比較用変数削除部173は,図28に示す結果データ185から,比較用の変数S3,S4のレコードを削除する。
図30は,本実施の形態による結果データの例を示す図である。
図28に示す結果データ185に対して,比較用変数削除部173による比較用の変数のレコードを削除する処理が行われると,結果データ185は,図30に示す通りとなる。
図31は,本実施の形態の比較用変数削除部による比較用変数削除処理フローチャートである。
図31に示すフローチャートは,図9に示すフローチャートのステップS21に示す比較用変数削除処理の一例である。
比較用変数削除部173は,変数宣言データ132のレコードを1つ選択する(ステップS150)。比較用変数削除部173は,選択されたレコードの型が数値型であるかを判定する(ステップS151)。選択されたレコードの型が数値型であれば(ステップS151のYES),結果データ185から,選択されたレコードの文字列型変数名が変数名であるレコードを削除する(ステップS152)。
比較用変数削除部173は,変数宣言データ132のすべてのレコードについて処理が終了したかを判定する(ステップS153)。すべてのレコードについて処理が終了していなければ(ステップS153のNO),比較用変数削除部173は,ステップS150の処理に戻って,次のレコードの処理に移る。すべてのレコードについて処理が終了していれば(ステップS153のYES),比較用変数削除部173は,処理を終了する。
このように,結果処理部170によって,制約ソルバの実行結果から得られる結果データ185から,制約記述の生成過程で設定された,実際のテストに不要なデータを自動で削除することが可能となる。
最終的に得られた図30に示す結果データ185が,テスト対象プログラム200に処理パス(4)を実行させることができる各データ項目の値となる。実際には,データ項目「規定値」,「発注量下限」,「発注量上限」の結果値は,テスト対象プログラム200内で設定された固定値であるので,テストで入力するのは,データ項目「発注量」の結果値“010”である。
得られたテストデータ“010”を「発注量」に入力してテスト対象プログラム200を実行すると,分岐[1]の判定結果がfalse ,分岐[2]の判定結果がfalse ,分岐[3]の判定結果がfalse となり,テスト対象プログラム200に処理パス(4)を実行させることができる。
以上説明したように,本実施の形態によるテストデータ生成装置100によって,桁の概念を持つプログラミング言語で記述されたプログラムに特定の処理パスを実行させる正しいテストデータを,容易に生成することが可能となる。
以上,本実施の形態について説明したが,本発明はその主旨の範囲において種々の変形が可能であることは当然である。