図5に、テスト対象クラスの例を示す。ここでは、テスト対象のクラス「TargetClass」に含まれるテスト対象メソッド「targetMethod2」の動作をテストすることを想定する。テスト対象メソッド「targetMethod2」は、オブジェクト型変数「obj1」とオブジェクト型変数「obj2」を入力する構成になっている。
図6に、ライブラリの例を示す。クラスAとクラスBとクラスCは、上述のテスト対象のクラス「TargetClass」で用いられる。クラスAは、メンバ変数a1を保持している。クラスBは、クラスAを継承している。つまり、Bは、親クラスAの子クラスである。クラスBは、メンバ変数b1を保持している。クラスCも、クラスAを継承している。つまり、Cも、親クラスAの子クラスである。
クラス「SymbolicExecUtil」が保持するメソッド「calcPathCondition(Object obj, String name)」は、オブジェクト指定命令である。オブジェクト指定命令は、パス条件の計算対象となるオブジェクト型変数を指定する命令である。シンボリック実行時にオブジェクト指定命令が呼ばれると、「obj」が参照するインスタンスについて、この命令以後のオブジェクトパス条件を計算する。また、オブジェクト指定命令は、オブジェクトパス条件内でobjを指す変数名としてnameを使うことも指定している。但し、通常のプログラム実行時にオブジェクト指定命令が呼ばれても、何もしない。
テストケース生成装置は、テスト対象クラスとテスト対象クラスが用いるライブラリ(例えば、クラスAとクラスBとクラスC)に基づいて、シンボル実行用ドライバを生成する。シンボル実行用ドライバは、初期設定やテスト対象の呼び出しを行うドライバである。テストケース生成装置は、シンボル実行用ドライバを生成するために、サンプルフォームを用いる。
図7に、シンボル実行用ドライバのサンプルフォームの例を示す。シンボル変数宣言エリア701は、シンボル変数の宣言を設定する領域である。対象クラス初期化エリア703は、対象クラスの初期化を設定する領域である。初期化コードエリア705は、パス条件の計算対象となるオブジェクト型変数を初期化するコードを設定する領域である。オブジェクト指定命令エリア707は、オブジェクト指定命令を設定する領域である。対象メソッドの呼び出しエリア709は、対象メソッド呼び出し命令を設定する領域である。
図8に、サンプルフォームを用いて生成されたシンボル実行用ドライバの例を示す。
コード801とコード803とコード805とコード807は、オブジェクト型変数P1に関するシンボル変数を宣言するコードである。尚、コード801とコード803は、制御変数の宣言であり、コード805とコード807は、メンバシンボル変数の宣言である。制御変数とメンバシンボル変数は、いずれもシンボル変数である。
コード809は、シンボリック実行による実行開始位置を示すコードである。コード811は、対象クラスの初期化を行うコードである。コード813は、オブジェクト型変数の宣言を行うコードである。コード815は、オブジェクト型変数のnull判定とnull値の代入を行うコードである。尚、elseにおける処理は、コード819によって閉じている。コード817は、オブジェクト型変数をクラス型に応じて初期化するコードである。コード821は、オブジェクト型変数をパス条件算出の対象とすることを指定するオブジェクト指定命令である。コード823は、テスト対象であるクラスを呼び出すコードである。
また、準備段階において、テスト対象クラスに基づいて制御変数テーブルも生成される。図9に、制御変数テーブルの例を示す。制御変数は、テスト対象メソッドへ入力されるオブジェクト型変数の状態を示している。この例で、制御変数P1_cnullは、オブジェクト型変数P1がnullであるか否かを示している。制御変数P1_cnullの値がtrueである場合には、オブジェクト型変数P1がnullであることを意味しており、意味式「P1==null」と同義である。制御変数P1_cnullの値がfalseである場合には、オブジェクト型変数P1がnullでないことを意味しており、意味式「P1!=null」と同義である。
この例で、制御変数P1_cClassは、オブジェクト型変数の実際のクラス型を示している。制御変数P1_cClassの値が0である場合には、オブジェクト型変数P1の実際の型がクラスAであることを意味しており、意味式「P1 instanceof A」と同義である。制御変数P1_cClassの値が1である場合には、オブジェクト型変数P1の実際の型がクラスBであることを意味しており、意味式「P1 instanceof B」と同義である。制御変数P1_cClassの値が0又は1以外である場合には、オブジェクト型変数P1の実際の型がクラスCであることを意味しており、意味式「P1 instanceof C」と同義である。尚、変数の入力方法は、参照可能な形式であればよく、引数形式に限らない。
まず、テストケース生成装置によりシンボル実行用ドライバと制御変数テーブルを生成する準備処理について説明する。図10に、テストケース生成装置のうち準備処理に係る構成例を示す。テストケース生成装置は、受付部1001、対象クラス格納部1003、ライブラリ格納部1005、サンプルフォーム格納部1007、ドライバ生成部1009、ドライバ格納部1011、制御変数テーブル生成部1013、及び制御変数テーブル格納部1015を有している。
受付部1001は、対象クラスとライブラリを受け付けるように構成されている。対象クラス格納部1003は、対象クラスを格納するように構成されている。ライブラリ格納部1005は、ライブラリを格納するように構成されている。サンプルフォーム格納部1007は、サンプルフォームを予め格納している。ドライバ生成部1009は、シンボル実行用ドライバを生成するように構成されている。ドライバ格納部1011は、シンボル実行用ドライバを格納するように構成されている。制御変数テーブル生成部1013は、制御変数テーブルを生成するように構成されている。制御変数テーブル格納部1015は、制御変数テーブルを格納するように構成されている。
図11に、準備処理フローの例を示す。受付部1001は、対象クラスとライブラリを受け付ける(S1101)。そして、ドライバ生成部1009は、ドライバ生成処理を行う(S1103)。続いて、制御変数テーブル生成部1013は、制御変数テーブル生成処理を行う(S1105)。制御変数テーブル生成処理(S1105)については、図24を用いて後述する。
図12に、ドライバ生成処理フローの例を示す。ドライバ生成部1009は、まずサンプルフォーム格納部1007からサンプルフォームを読み出す(S1201)。そして、ドライバ生成部1009は、シンボル変数宣言処理を行う(S1203)。
図13に、シンボル変数宣言処理フローの例を示す。ドライバ生成部1009は、対象メソッドの入力変数を特定する(S1301)。例えば、図5では、「A obj1」と「A obj2」が入力変数である。尚、図1の例であれば、入力変数は「int a」と「int b」が入力変数である。
そして、ドライバ生成部1009は、入力変数毎に以下の処理を繰り返す(S1303)
ドライバ生成部1009は、入力変数の型がオブジェクト型であるか、あるいはプリミティブ型であるかを判定する(S1305)。例えば、入力変数が「A obj1」であれば、オブジェクト型であると判定し、入力変数が「int a」であれば、プリミティブ型であると判定する。
まず、入力変数の型がオブジェクト型と判定された場合について説明する。ドライバ生成部1009は、制御変数宣言処理を行う(S1307)。
図14に、制御変数宣言処理フローの例を示す。ドライバ生成部1009は、規約に従ってnull制御変数名を決める(S1401)。この例で、i番目の入力変数に対するnull制御変数名は、「Pi_cnull」となる。そして、ドライバ生成部1009は、サンプルフォームのシンボル変数宣言エリア701に「@Symbolic(”true”)」の行を追加し(S1403)、更に「public static boolean;」の行を加える(S1405)。そして、ドライバ生成部1009は、boolean型のnull制御変数名を挿入する(S1407)。更に、ドライバ生成部1009は、null制御変数に具体値を代入するようにしてもよい。このようにして、例えば図8に示した801の宣言が生成される。
続いて、ドライバ生成部1009は、規約に従って実際型制御変数名を決める(S1409)。この例で、i番目の入力変数に対する実際型制御変数名は、「Pi_cClass」となる。ドライバ生成部1009は、サンプルフォームのシンボル変数宣言エリア701に「@Symbolic(”true”)」の行を追加し(S1411)、更に、「public static int;」の行を加え(S1413)。そして、ドライバ生成部1009は、int型の実際型制御変数名を挿入する(S1415)。ドライバ生成部1009は、実際型制御変数に具体値を代入するようにしてもよい。このようにして、例えば図8に示した803の宣言が生成される。
図13の処理に戻って、ドライバ生成部1009は、メンバ宣言処理を行う(S1309)。
図15に、メンバ宣言処理フローの例を示す。ドライバ生成部1009は、オブジェクト型変数として保持し得るメンバ変数毎に以下の処理を繰り返す(S1501)。ドライバ生成部1009は、規約に従ってメンバシンボル変数名を決める(S1503)。この例で、i番目の入力変数のメンバ変数Mに対するメンバシンボル変数名は、「Pi_mM」となる。ドライバ生成部1009は、サンプルフォームのシンボル変数宣言エリア701に「@Symbolic(”true”)」の行を追加し(S1505)、更に、「public static ;」の行を加える(S1507)。そして、ドライバ生成部1009は、データの型を挿入し(S1509)、メンバシンボル変数名を挿入する(S1511)。ドライバ生成部1009は、メンバシンボル変数に具体値を代入するようにしてもよい。このようにして、例えば図8に示した805と807の宣言が生成される。ドライバ生成部1009は、すべてのメンバ変数について処理したか否かを判定する(S1513)。処理していないメンバ変数があると判定した場合には、S1501へ戻る。すべてのメンバ変数について処理したと判定した場合には、ドライバ生成部1009は処理を終え、図13のS1311へ戻る。
図13の処理に戻って、ドライバ生成部1009は、初期化コード処理を行う(S1311)。
図16に、初期化コード処理フローの例を示す。ドライバ生成部1009は、規約に従ってオブジェクト型変数名を決める(S1601)。この例で、i番目の入力変数名は、プリミティブ型変数であるかオブジェクト型変数であるかを問わず、「Pi」となる。ドライバ生成部1009は、サンプルフォームの初期化コードエリア705にオブジェクト型変数の宣言を追加する(S1603)。具体的には、クラス型とオブジェクト変数名が設定される。このようにして、例えば図8に示した813の宣言が生成される。
続いて、ドライバ生成部1009は、null化処理を行う(S1605)。図17に、null化処理フローの例を示す。ドライバ生成部1009は、サンプルフォームの初期化コードエリア705に判定制御コードを追加する(S1701)。この例では、判定制御コードとして図8の815と819に示した「if(){}else{}」(改行省略)を追加する。ドライバ生成部1009は、null判定条件を挿入する(S1703)。この例では、if文の()内にnull制御変数名を挿入する。ドライバ生成部1009は、if文の判定が真の場合に、null制御変数名へnullを代入する命令を追加し(S1705)、処理を終える。
図16の処理に戻って、ドライバ生成部1009は、クラス判定処理を行う(S1607)。ドライバ生成部1009は、クラス判定処理で(S1607)、例えば図8の817のコードを設定する。
図18に、クラス判定処理フローの例を示す。ドライバ生成部1009は、サンプルフォームの初期化コードエリア705に分岐制御コードを追加する(S1801)。この例では、if文の判定が偽の場合の分岐制御コードとして「switch(){case:break;case:break;default:break;}」(改行省略)を追加する。ドライバ生成部1009は、分岐条件を挿入し(S1803)、処理を終える。この例では、switch文の()内に実際型制御変数名「P1_cClass」を挿入し、各caseの後に「0」と「1」を挿入する。
図16の処理に戻って、ドライバ生成部1009は、オブジェクト型変数初期化処理を行う(S1609)。ドライバ生成部1009は、オブジェクト型変数初期化処理(S1609)で、オブジェクト型変数の型の候補となるクラス型毎の初期化のコードを設定する。
図19に、オブジェクト型変数初期化処理フローの例を示す。ドライバ生成部1009は、候補となるクラス型毎に以下の処理を繰り返す(S1901)。ドライバ生成部1009は、オブジェクト型変数生成の命令を追加する(S1903)。例えばクラス型がAの場合には、「(オブジェクト型変数)=new A();」のコードを追加する。ドライバ生成部1009は、更に候補のクラス型で保持し得るメンバ変数についてメンバ初期化の命令を追加する(S1905)。具体的には、「(メンバ変数)=(メンバシンボル変数名);」のコードを追加する。ドライバ生成部1009は、すべての候補となるクラス型について処理したか否かを判定する(S1907)。処理していないクラス型があると判定した場合には、ドライバ生成部1009はS1901に戻る。すべての候補となるクラス型について処理したと判定した場合には、ドライバ生成部1009は処理を終え、図16の処理へ戻る。このようにして、例えば図8に示した817のコードが設定される。更に、ドライバ生成部1009は図16の処理を終え、図13のS1313へ戻る。
図13の処理に戻って、ドライバ生成部1009は、オブジェクト指定命令処理を行う(S1313)。ドライバ生成部1009は、オブジェクト指定命令処理(S1313)で、例えば、図8に示した821のコードを設定する。
図20に、オブジェクト指定命令処理フローの例を示す。ドライバ生成部1009は、サンプルフォームのオブジェクト指定命令エリア707にオブジェクト指定命令「SymbolicExecUtil.calcPathCondition();」の行を追加する(S2001)。ドライバ生成部1009は、オブジェクト指定命令の引数にオブジェクト型変数名を挿入する(S2003)。
また、ドライバ生成部1009は、パス条件用変数名を特定する(S2005)。パス条件用変数名は、このオブジェクト型変数についてのパス条件を生成する際に用いる変数名である。この例では、パス条件用変数名は、オブジェクト型変数名と同じである。ドライバ生成部1009は、オブジェクト指定命令の引数にパス条件用変数名を挿入する(S2007)。ドライバ生成部1009は図20の処理を終え、図13のS1317へ戻る。
次に、図13の処理に戻って、S1305で入力変数の型がプリミティブ型と判定された場合について説明する。
S1305で入力変数の型がプリミティブ型と判定された場合には、ドライバ生成部1009は、プリミティブ宣言処理を行う(S1315)。図21に、プリミティブ宣言処理フローの例を示す。ドライバ生成部1009は、規約に従ってプリミティブ型変数名を決める(S2101)。この例で、i番目の入力変数名は、プリミティブ型変数であるかオブジェクト型変数であるかを問わず、「Pi」となる。ドライバ生成部1009は、サンプルフォームのシンボル変数宣言エリア701に「@Symbolic(”true”)」の行を追加する(S2103)。ドライバ生成部1009は、「public static ;」の行を加える(S2105)。ドライバ生成部1009は、プリミティブ型変数のデータ型を挿入する(S2107)。ドライバ生成部1009は、シンボル変数名を挿入する(S2109)。このようにして、例えば図3の301のコードが設定される。ドライバ生成部1009は図21の処理を終えると、図13のS1317へ戻る。
図13の処理に戻って、ドライバ生成部1009は、すべての引数について処理したか否かを判定する(S1317)。処理していない引数があると判定した場合には、ドライバ生成部1009はS1301へ戻る。すべての引数について処理したと判定した場合には、ドライバ生成部1009は図13の処理を終え、図12のS1205へ戻る。
図12の処理に戻って、ドライバ生成部1009は、対象クラス初期化処理(S1205)で、対象クラスを初期化するコードを設定する。
図22は、対象クラス初期化処理フローの例を示す図である。ドライバ生成部1009は、図7に示したサンプルフォームの対象クラス初期化エリア703に「TargetClass target = new ();」の行を追加する(S2201)。ドライバ生成部1009は、対象クラス名を特定し(S2203)、「()」の前に挿入し(S2205)、処理を終える。このようにして、図8に示した811のコードが設定される。
図22の処理を終えると、図12の処理に戻って、ドライバ生成部1009は、対象メソッド呼び出し処理を行う(S1207)。
図23に、対象メソッド呼び出し処理フローの例を示す。ドライバ生成部1009は、図7に示したサンプルフォームの対象メソッドの呼び出しエリア709に「target.();」 の行を追加する(S2301)。ドライバ生成部1009は、対象メソッド名を特定し(S2303)、「.」の後に挿入する(S2305)。更に、ドライバ生成部1009は、引数に設定する変数名を挿入し(S2307)、処理を終える。ドライバ生成部1009は図12の対象メソッド呼び出し処理(S1207)を終え、更に図11のドライバ生成処理(S1103)を終える。
続いて、図11の処理に戻って、S1105に示した制御変数テーブル生成処理について説明する。制御変数テーブル生成部1013は、制御変数テーブル生成処理で、例えば図9に示した制御変数テーブルを生成する。
図24に、制御変数テーブル生成処理フローの例を示す。制御変数テーブル生成部1013は、対象メソッドの入力変数を特定し(S2401)、入力変数毎に以下の処理を繰り返す(S2403)。制御変数テーブル生成部1013は、入力変数の型がオブジェクト型であるか、あるいはプリミティブ型であるかを判定する(S2405)。入力変数の型がプリミティブ型であると判定した場合には、制御変数テーブル生成部1013はS2417を行う。
入力変数の型がオブジェクト型であると判定した場合には、制御変数テーブル生成部1013は、図14のS1401で決めたnull制御変数名を設定する(S2407)。そして、制御変数テーブル生成部1013は、trueと意味式を設定する(S2409)。意味式は、「(オブジェクト型変数名)==null」となる。制御変数テーブル生成部1013は、更にfalseと意味式を設定する(S2411)。意味式は、「(オブジェクト型変数名)!=null」となる。
次に、制御変数テーブル生成部1013は、図14のS1409で決めた実際型制御変数名を設定する(S2413)。更に、制御変数テーブル生成部1013は、候補クラスを示す値と意味式を設定する(S2415)。値に応じて、「(オブジェクト型変数名) instanceof (候補クラス名)」とする。制御変数テーブル生成部1013は、すべての入力変数について処理した否かを判定する(S2417)。処理していない入力変数があると判定した場合には、制御変数テーブル生成部1013はS2403に戻る。すべての入力変数について処理したと判定した場合には、制御変数テーブル生成部1013は処理を終え、図11に戻り、準備処理を終える。
このように準備処理において、シンボル実行用ドライバと制御変数テーブルを生成することにより、テストケース生成作業の省力化が図られる。
続いて、シンボリック実行処理について説明する。図25は、テストケース生成装置のうちシンボリック実行処理に係る構成例を示す図である。テストケース生成装置は、更に、実行部1017、パターンテーブル格納部1019、シンボル変数テーブル記憶部1021、特定部1023、オブジェクトテーブル記憶部1025、第1テストケース格納部1027、第1生成部1029及びオブジェクトパス条件記憶部1031を有している。
実行部1017は、シンボリック実行を行い、第1テストケースを生成するように構成されている。パターンテーブル格納部1019は、プログラムパターンとメモリ条件パターンとパス条件パターンを対応付けるパターンテーブルを記憶するように構成されている。パターンテーブル格納部1019については、図26を用いて後述する。
シンボル変数テーブル記憶部1021は、シンボル変数とその型を対応付けるシンボル変数テーブルを記憶するように構成されている。特定部1023は、オブジェクト型変数の実体が格納されている位置を特定したオブジェクトテーブルを生成する処理を行うように構成されている。オブジェクトテーブル記憶部1025は、オブジェクトテーブルを記憶するように構成されている。第1テストケース格納部1027は、第1テストケースの集合である第1テストケースセットを記憶するように構成されている。第1生成部1029は、オブジェクトテーブルに基づいて、オブジェクト型変数が満たすべきオブジェクトパス条件を生成する処理を行うように構成されている。オブジェクトパス条件記憶部1031は、オブジェクトパス条件を記憶するように構成されている。
図26に、パターンテーブルの例を示す。パターンテーブルは、パターン番号、プログラムパターン、メモリ条件パターン及びパス条件パターンを対応付けている。プログラムに含まれる式のパターンにより導かれるオブジェクトパス条件のパターンを定めている。更に、プログラムに含まれる式のパターンに加えて、メモリの条件も加えて判断する場合のメモリ条件のパターンも定めている。
メモリ条件パターンが設定されていない場合には、プログラムパターンからパス条件パターンが導かれ、メモリ条件パターンが設定されている場合には、プログラムパターン及びメモリ条件パターンからパス条件パターンが導かれる。
「OBJX」と「OBJY」は、オブジェクトパス条件を計算する対象となるオブジェクト変数を示している。例えば、パターン番号1に示したように、プログラム中の命令に「OBJX==null」の式が含まれる場合には、パス条件として「OBJX==null」が導かれる。
また、「TX」は、型を示している。例えば、パターン番号3に示したように、プログラム中の命令に「OBJX instanceof TX」の式が含まれる場合には、パス条件として「OBJX instanceof TX」が導かれる。
「.member」は、メンバ変数へのアクセスを示している。例えば、パターン番号5に示したように、プログラム中の命令に「OBJX.member」の式が含まれる場合には、パス条件として「OBJX!=null」が導かれる。
「.method()」は、メソッドの呼び出しを示している。例えば、パターン番号6に示したように、プログラム中の命令に「OBJX.method()」の式が含まれる場合には、パス条件として「OBJX!=null」が導かれる。
「VX」と「VY」は、オブジェクトパス条件を計算する対象とならない変数を示している。例えば、パターン番号7に示したように、プログラム中の命令に「OBJX==VX」の式が含まれ、更にメモリの状態が「VX==null」であれば、パス条件として「OBJX==null」が導かれる。
図27に、シンボル変数テーブル記憶部1021で記憶されるシンボル変数テーブルの例を示す。このように、シンボル変数テーブル記憶部1021は、シンボル変数とその型を対応付ける。
図28に、オブジェクトテーブル記憶部1025で記憶されるオブジェクトテーブルの例を示す。図28に示したように、オブジェクトパス条件を計算する対象となるオブジェクト型変数名と、参照用IDと、パス条件用変数名を対応付けている。参照用IDは、オブジェクト型変数のインスタンスを参照するための情報である。パス条件用変数名は、オブジェクトパス条件で用いるオブジェクト型変数の変数名である。オブジェクト型変数名は、省略してもよい。
図29a乃至図29cに、第1テストケース格納部1027で記憶される第1テストケースセットの例を示す。テストケースを識別するケース番号と、テスト入力と、シンボルパス条件を対応付けている。第1テストケースは、シンボリック実行処理により生成される。
図30に、オブジェクトパス条件記憶部1031で記憶されるオブジェクトパス条件の例を示す。テストケースを識別するケース番号とオブジェクトパス条件を対応付けている。例えば、ケース番号1の場合、「P1_cnull==true∧P2_cnull ==true」がオブジェクトパス条件となることを示している。オブジェクトパス条件は、第1生成部1029により生成される。
続いて、シンボリック実行処理について説明する。図31に、シンボリック実行処理フローの例を示す。実行部1017は、まず初期化処理を行う(S3101)。
図32に、初期化処理フローの例を示す。実行部1017は、シンボル変数テーブルを生成する(S3201)。シンボル変数テーブルは、シンボル実行用ドライバのシンボル変数宣言から抽出される。シンボル変数テーブルは、シンボル変数を特定するために用いられる。実行部1017は、実行開始位置を特定する(S3203)。実行開始位置は、図8の809のコードにより特定される。実行部1017は、第1テストケースに新規レコードを割り当てる(S3205)。このとき、ケース番号も割り振られる。実行部1017は処理を終了し、図31のS3103へ戻る。
図31の処理に戻って、実行部1017は、実行パターン処理を行う(S3103)。実行パターン処理では、実行パターン毎の処理を行う。図33に、実行パターン処理フローの例を示す。実行部1017は、実行開始位置から順に命令を特定する(S3301)。実行部1017は、命令が有るか否かを判定する(S3303)。命令が無いと判定した場合には、実行パターンの終点であるので、実行部1017は、処理結果を完了として処理を終了する(S3305)。実行部1017が処理を終えると、図31のS3105へ戻る。
図33のS3303で命令が有ると判定した場合には、実行部1017は、命令がオブジェクト指定命令であるか否かを判定する(S3307)。オブジェクト指定命令は、例えば図8に示した821のコードである。命令がオブジェクト指定命令でないと判定した場合には、実行部1017はS3311へ処理を移す。命令がオブジェクト指定命令であると判定した場合には、特定部1023は、オブジェクト特定処理を行う(S3309)。
ここで、オブジェクト指定命令を判定する実行パターン処理の動作例を説明する。図34に、実行パターン処理の動作例を示す。シンボル実行用ドライバと対象メソッド中の命令の遷移を、矢印で示している。「if(P1_cnull)」の条件判断で、「true」と判断され、シンボルパス条件「P1_cnull==true」が生成される。また、「if(P2_cnull)」の条件判断で、「true」と判断され、シンボルパス条件「P2_cnull==true」が生成される。
「SymbolicExecUtil.calcPathCondition(P1, “P1”);」と「SymbolicExecUtil.calcPathCondition(P2, “P2”);」の行で、オブジェクト指定命令と判定され、オブジェクト特定処理が行われる。
続けて、図33のオブジェクト特定処理(S3309)の説明をする。図35に、オブジェクト特定処理フローの例を示す。特定部1023は、オブジェクト指定命令の引数であるオブジェクト型変数名を特定する(S3501)。図34の例では、それぞれ「P1」と「P2」がオブジェクト型変数名である。特定部1023は、オブジェクト型変数名を実行部1017へ渡し、実行部1017からオブジェクト型変数のインスタンスを参照するための参照用IDを取得する(S3503)。このとき、実行部1017は、オブジェクト型変数名を受け、そのオブジェクト型変数のインスタンスを参照するための参照用IDを返すように動作する。特定部1023は、オブジェクト指定命令の引数であるパス条件用変数名を特定する(S3505)。図34の例では、それぞれ「“P1”」と「“P2”」がパス条件用変数名である。特定部1023は、オブジェクト型変数名と参照用IDとパス条件用変数名を対象テーブルのレコードに追加する(S3507)。特定部1023は処理を終え、図33のS3311へ戻る。
図33の処理に戻って、実行部1017は、S3301で特定した命令を解析し(S3311)、その命令が分岐命令であるか否かを判定する。(S3313)。その命令が分岐命令でないと判定した場合には、S3317へ移る。その命令が分岐命令であると判定した場合には、実行部1017は、未だパスとして選択していない分岐を選択する(S3315)。そして、実行部1017は、選択した分岐についてのシンボルパス条件を計算する(S3317)。但し、S3313で分岐命令でないと判定し、シンボルパス条件の計算を行なわない場合もある。シンボルパス条件の計算については、従来のシンボリック実行の場合と同様であるので、説明を省略する。
続いて、第1生成部1029は、オブジェクトパス条件生成処理を行う(S3319)。オブジェクトパス条件生成処理については、図38から図40を用いて後述する。
実行部1017は、パス条件の充足は可能であるか否かを判定する(S3321)。パス条件を充足できないと判定した場合には、実行不可能なパス(例えば、図2の203)を含むので、実行部1017は、処理結果を中断とする(S3323)。パス条件を充足できると判定した場合には、実行部1017は、命令を実行し(S3325)、S3301へ戻る。
図36に、図34の次の実行パターン処理の動作例を示す。図34で「return 0」に至り、図33のS3303とS3305で示したように次の命令が無いと判定すると、処理結果を完了として一旦実行パターン処理を終える。そして、未実行パスを選択する。具体的には、バックトラックにより未選択の分岐がある分岐点までもどり、未選択の分岐を次のパスの実行開始位置とする。図36の例では、次の実行開始位置「if(P2_cnull)」の判断結果「false」を選択する。このとき、実行開始位置「if(P2_cnull)」までに得られている既知のシンボルパス条件「P1_cnull==true」が特定され、新しいシンボルパス条件に設定される。そして、シンボルパス条件「P2_cnull==false」が生成される。
図31の処理に戻って、実行部1017は、S3103の実行パターン処理における処理結果が中断であるか、あるいは完了であるかを判定する(S3105)。処理結果が中断であると判定した場合には、実行部1017はテストケースを生成しない。処理結果が完了であると判定した場合には、実行部1017はテストケースを生成する(S3107)。具体的には、実行部1017は、シンボリックパス条件の充足値を求めて、その充足値をテスト入力に設定する。
次に、実行部1017は、探索処理を行う(S3109)。探索処理では、次のパスを探索する。
図37に、探索処理フローの例を示す。実行部1017は、未実行パスを選択する(S3701)。具体的には、実行部1017は、図36に示したように、バックトラックにより未選択の分岐がある分岐点までもどり、未選択の分岐を次のパスの実行開始位置とする。実行部1017は、未実行パスあったか否かを判定する(S3703)。バックトラックにより未選択の分岐が見つけられなかった場合には、実行部1017は未実行パスがないと判定して、処理結果をパスなしとする(S3705)。そして、実行部1017は処理を終え、図31のS3111へ戻る。
バックトラックにより未選択の分岐が見つかった場合には、実行部1017は未実行パスがあると判定して、第1テストケースの新規レコードを割り当てる(S3707)。そして、実行部1017は、分岐点より上位の既知であるシンボリックパス条件を特定し、新たな第1テストケースのシンボリックパス条件に加える(S3709)。そして、実行部1017は、処理結果をパスありとして(S3711)、処理を終了する。そして、図31のS3111へ戻る。
図31の処理に戻って、実行部1017は、探索処理(S3109)の処理結果がパスありであるか、あるいはパスなしであるかを判定する(S3111)。探索処理(S3109)の処理結果がパスありであると判定すると、実行部1017はS3103の処理に戻り、シンボリック実行処理を続行する。探索処理(S3109)の処理結果がパスなしであると判定すると、実行部1017はシンボリック実行処理を終える。
次に、前述のオブジェクトパス条件生成処理(図33のS3319)について説明する。
ここで、図38にオブジェクトパス条件生成の動作例を示す。図38の例では、条件判断命令「if(obj1!=null)」から選択した分岐を示す式「obj1!=null」を得る。そして、オペランド「obj1」を参照先となるID「100」を特定する。この参照先ID「100」は、オブジェクトテーブルの参照用ID「100」と一致するので、このオペランドの変数はオブジェクトパス条件の計算対象であると判定される。そして、式「obj1!=null」に相当するプログラムパターン「OBJX!=null」をパターンテーブルで特定し、プログラムパターンに対応するパス条件パターン「OBJX!=null」に基づいて、オブジェクトパス条件「P1!=null」を生成している。その際、参照用ID「100」に対応するパス条件用変数名「P1」を用いている。尚、この例では、メモリ条件パターンは設定されていないので、メモリの状態については判定しない。
図39に、オブジェクトパス条件生成処理フローの例を示す。第1生成部1029は、命令から式を特定し(S3901)、第1生成部1029は、オペランドの変数を特定する(S3903)。条件判断命令の場合には、第1生成部1029は選択した分岐を示す式を特定する。
そして、第1生成部1029は、変数の参照先IDを実行部1017から取得する(S3905)。このとき、第1生成部1029は変数名を実行部1017に渡す。これに対して、実行部1017はその変数名によるインスタンスを参照するためのIDを返すように動作する。第1生成部1029は、取得した参照先IDがオブジェクトテーブルのいずれかの参照用IDと一致するか否かを判定する(S3907)。取得した参照先IDがオブジェクトテーブルのいずれの参照用IDとも一致しないと判定した場合には、第1生成部1029は処理を終え、図33のS3321へ戻る。
図39のS3907で、取得した参照先IDがオブジェクトテーブルのいずれかの参照用IDと一致すると判定した場合には、第1生成部1029は、S3901で特定した式に対応するプログラムパターンを特定する(S3909)。S3901で特定した式が否定形式の場合には、肯定形式の式に置き換えてプログラムパターンと対比するようにしてもよい。第1生成部1029は、パターンテーブルにプログラムパターンに対応するメモリ条件パターンがあるか否かを判定する(S3911)。パターンテーブルにプログラムパターンに対応するメモリ条件パターンないと判定した場合には、第1生成部1029はS3917へ移る。
パターンテーブルにプログラムパターンに対応するメモリ条件パターンあると判定した場合には、第1生成部1029は、メモリ条件パターンに関するメモリ情報を取得する(S3913)。例えば、第1生成部1029は「VX」に相当する変数名を実行部1017へ渡し、実行部1017はメモリに格納されている変数の値又はnullを返す。あるいは、別の例で第1生成部1029は「OBJX」に相当するオブジェクト型変数がnullであるか否かを問い合わせる要求を実行部1017へ渡し、実行部1017は「OBJX」に相当するオブジェクト型変数がnullであるか否かを示す回答を返す。
そして、第1生成部1029は、メモリ情報がメモリ条件パターンに合致するか否かを判定する(S3915)。メモリ情報がメモリ条件パターンに合致しないと判定した場合には、第1生成部1029は処理を終了し、図33のS3321へ戻る。
メモリ情報がメモリ条件パターンに合致すると判定した場合には、第1生成部1029は、オブジェクトパス条件を生成する(S3917)。具体的には、プログラムパターンに対応するパス条件パターンを特定し、パス条件パターンに基づいて、オブジェクトパス条件を生成する。その際、パス条件パターン中のオブジェクト変数(例えば「OBJX」)を、そのオブジェクト変数に相当するオブジェクト変数(「例えば、P1」)に対応するパス条件用変数名(例えば、「”P1”」)に変換する。尚、前述のように、特定した式が否定形式の場合であり、式を肯定形式に置き換えてプログラムパターンを特定した場合には、オブジェクトパス条件も肯定形式から否定形式に変換する。そして、第1生成部1029は、生成したオブジェクトパス条件をオブジェクトテーブル記憶部1025にケース番号に対応付けて記憶させる(S3919)。
図40に、図38に続くオブジェクトパス条件生成の動作例を示す。図40の例では、条件判断命令「if(obj1 instanceof B)」で偽が選択されたと想定し、分岐を示す式「!(obj1 instanceof B)」を得る。そして、オペランド「obj1」の参照先となるID「100」を特定する。この参照先ID「100」は、オブジェクトテーブルの参照用ID「100」と一致するので、このオペランドの変数はオブジェクトパス条件の計算対象であると判定される。そして、式「obj1 instanceof B」に相当するプログラムパターン「OBJX instanceof TX」をパターンテーブルで特定し、プログラムパターンに対応するパス条件パターン「OBJX instanceof TX」に基づいて、オブジェクトパス条件「!(P1 instanceof B)」を生成する。その際、参照用ID「100」に対応するパス条件用変数名「P1」を用いている。また、「TX」は対応する「B」に置き換えている。この例では、式が否定形式であるので、オブジェクトパス条件も否定形式となっている。
前述の参照用IDは、オブジェクト変数のインスタンスを参照する情報である。図41に、メモリ状態の例を示す。スタックでは、変数毎に変数名と型と参照用IDを記憶している。ヒープでは、インスタンスを格納している。インスタンスは、参照用IDによって特定できるように構成されている。例えば、「obj1.a1」のメンバ変数の値を取得する場合には、スタックの情報に基づいて「obj1」の変数名に対応する参照用ID「100」を特定し、更に参照用ID「100」で特定されるインスタンスから、メンバ変数の値を取得する。通常の実行においては、メンバ変数には具体的な値が設定されているが、シンボリック実行においては、シンボル変数として宣言されているメンバ変数には、シンボル値が設定されている。図中、「symbol_P1_ma1」と「symbol_P2_ma1」は、シンボル値の例である。
複数の変数から同じインスタンスを参照する場合もある。図42に、複数の変数から同じインスタンスを参照する場合の例を示す。例えば、「(B)obj1.b1」のメンバ変数の値を取得する場合には、内部処理によってスタックに「obj1」と同じインスタンスを指すクラスB型の変数「tmp1」を用意する。そして、「tmp1」の変数名に対応する参照用ID「100」を特定し、更に参照用ID「100」で特定されるインスタンスから、メンバ変数の値を取得する。この場合も、シンボル変数として宣言されているメンバ変数にはシンボル値が設定されている。図中、「symbol_P1_mb1」は、シンボル値の例である。
上述のようにシンボリック実行処理により、第1テストケースセットとオブジェクトパス条件が生成される。図29a〜図29cに示した26の第1テストケースセットは、想定されるオブジェクト型変数の状態の組合せを網羅している。制御情報である「P1_cnull」、「P2_cnull」、「P1_cClass」、あるいは「P2_cClass」を含むシンボルパス条件により、想定されるオブジェクト型変数の状態を読み取ることができる。
但し、これらの制御情報を含むシンボルパス条件は、シンボル実行用ドライバの初期化コード(例えば、図8の815と817)での分岐により生成されたものであって、テスト対象のプログラムにおける分岐に基づくものではない。従って、これらの制御情報を含むパス条件は、テストケースを欠落させることなく抽出するためには役立つが、テスト対象のプログラムに対するコードカバレッジを判断するためには不適切なデータであると言える。
一方、オブジェクトパス条件は、テスト対象のプログラムにおけるオブジェクト型変数の状態に関する分岐によるパス条件であり、テスト対象のプログラムに対するコードカバレッジを判断するのに適切なデータであると言える。
以下で説明するパス条件更新処理では、第1テストケースに含まれる制御変数を含むシンボルパス条件を除き、オブジェクトパス条件を加えた第2テストケースを生成する。第2テストケースは、テスト対象のプログラムに対するコードカバレッジの判断に適した対象内パス条件を備える。
また、パス条件更新処理に続くテストケース抽出処理では、第2テストケースセットから重複するテストケースを排除した第3テストケースセットを生成する。第3テストケースセットによるコードカバレッジは、第2テストケースセットによるコードカバレッジと等しい。
続いて、パス条件更新処理とテストケース抽出処理について説明する。図43は、テストケース生成装置のうちパス条件更新とテストケース抽出に係る構成例を示す図である。テストケース生成装置は、更に、第2生成部1033、第2テストケース格納部1035、抽出部1037、第3テストケース格納部1039及びテストケース出力部1041を有している。第2生成部1033は、パス条件を更新し、第2テストケースを生成するように動作する。第2テストケース格納部1035は、第2テストケースセットを記憶するように構成されている。抽出部1037は、第2テストケースセットから第3テストケースを抽出するように動作する。第3テストケース格納部1039は、第3テストケースの集合である第3テストケースセットを記憶するように構成されている。テストケース出力部1041は、第3テストケースセットを出力するように動作する。
図44に、パス条件更新の概要を示す。第1テストケースのシンボルパス条件のうち、制御変数を含まないシンボルパス条件のみが第2テストケースの対象内パス条件にコピーされる。図44の例では、シンボルパス条件「(P2_ma1>P1_ma1)」が対象内パス条件にコピーされている。シンボルパス条件「P1_cnull==false」は、制御変数「P1_cnull」を含んでいるので、対象内パス条件にコピーされない。同様に、シンボルパス条件「P1_cClass==0」は、制御変数「P1_cClass」を含んでいるので、対象内パス条件にコピーされない。同様に、シンボルパス条件「P2_cnull==false」は、制御変数「P2_cnull」を含んでいるので、対象内パス条件にコピーされない。同様に、シンボルパス条件「P2_cClass==0」は、制御変数「P2_cClass」を含んでいるので、対象内パス条件にコピーされない。
また、オブジェクトパス条件が第2テストケースの対象内パス条件にコピーされる。オブジェクトパス条件は、コピーの際に制御変数が満たすべき条件の形式に変換される。図44の例では、オブジェクトパス条件「P1!= null」は、対象内パス条件「P1_cnull==false」に変換されている。オブジェクトパス条件「!(P1 instanceof B)」は、対象内パス条件「P1_cClass!=1」に変換されている。オブジェクトパス条件「P2!=null」は、対象内パス条件「P2_cnull==false」に変換されている。オブジェクトパス条件「(P2.ma1>P1.ma1)」は、対象内パス条件「(P2_ma1>P1_ma1)」に変換されている。対象内パス条件「(P2_ma1>P1_ma1)」は、シンボルパス条件と重複しているので、1つの対象内パス条件のみ設定される。このように、オブジェクトパス条件とシンボルパス条件の一部が重複することも想定される。
制御変数が満たすべき条件の形式に変換することによって、テスト入力との関係を把握しやすくなる。
更に、第1テストケースのテスト入力が第2テストケースのテスト入力にコピーされる。
テスト入力「P1_cnull=false」と、テスト入力「P1_cClass=0」と、テスト入力「P1_ma1=0」と、テスト入力「P2_cnull=false」と、テスト入力「P2_cClass=0」と、テスト入力「P2_ma1=1」が、第1テストケースから第2テストケースへコピーされている。
図45に、第2テストケース生成処理フローの例を示す。第2生成部1033は、ケース番号毎に以下の処理を繰り返す(S4501)。第2生成部1033は、更にシンボルパス条件毎に以下の処理を繰り返す(S4503)。第2生成部1033は、シンボルパス条件が制御変数名を含むか否かを判定する(S4505)。シンボルパス条件が制御変数名を含ないと判定した場合には、第2生成部1033は、シンボルパス条件をコピーする(S4507)。一方、シンボルパス条件が制御変数名を含むと判定した場合には、第2生成部1033は、シンボルパス条件をコピーしない。第2生成部1033は、すべてのシンボルパス条件について処理したか否かを判定する(S4509)。処理していないシンボルパス条件があると判定した場合には、第2生成部1033はS4503へ処理を戻す。すべてのシンボルパス条件について処理したと判定した場合には、第2生成部1033はS4511へ処理を移す。
続いて、第2生成部1033は、オブジェクトパス条件毎に以下の処理を繰り返す(S4511)。第2生成部1033は、制御変数テーブルでオブジェクトパス条件と一致する意味式を特定する(S4513)。第2生成部1033は、意味式に対応する制御変数名と値を特定し、制御変数と値を用いた対象内パス条件を生成し、第2テストケースに加える(S4515)。例えば、図44の例でオブジェクト条件「P1!=null」と一致する意味式「P1!=null」に対応する制御変数名「P1_cnull」と値「false」を特定する。そして、対象内パス条件「P1_cnull==false」を生成する。
オブジェクトパス条件が否定形式である場合であり、オブジェクトパス条件を肯定形式に置き換えて意味式を特定するようにしてもよい。その場合には、制御変数と値を用いたパス条件を否定形式に置き換えることによって対象内パス条件を生成する。
例えば、図44の例で否定形式のオブジェクトパス条件「!(P1 instanceof B)」を肯定形式「P1 instanceof B」に置き換えて、意味式「P1 instanceof B」を特定する。そして、意味式「P1 instanceof B」に対応する制御変数名「P1_cClass」と値「1」を特定し、パス条件「P1_cClass==1」を生成し、否定形式に置き換えて対象内パス条件「P1_cClass!=1」を生成する。
尚、制御変数ではないメンバ変数についても、メンバ変数の変換規則に従って対象内パス条件に変換するようにしてもよい。図44の例で、例えば変換規則で、「P2.ma1」が「P2_ma1」に相当し、「P1.ma1」が「P1_ma1」に相当すると規定されている場合には、オブジェクト条件「P2.ma1>P1.ma1」は、対象内パス条件「P2_ma1>P1_ma1」に変換される。
図44に示したように、シンボル変数「P1_ma1」とシンボル変数「P2_ma1」に関するシンボルパス条件「P2_ma1>P1_ma1」も同じ内容である。このように同じ内容である場合には、対象内パス条件には1つだけ設定される。第2生成部1033は、すべてのオブジェクトパス条件について処理したか否かを判定する(S4517)。処理していないオブジェクトパス条件があると判定した場合には、S4511へ戻る。
一方、すべてのオブジェクトパス条件について処理したと判定した場合には、第2生成部1033は、第1テストケースのテスト入力を第2テストケースにコピーする(S4519)。第2生成部1033は、すべてのケース番号について処理したか否かを判定する(S4521)。処理していないケース番号があると判定した場合には、第2生成部1033はS4501へ処理を戻す。すべてのケース番号について処理した場合には、第2生成部1033は処理を終了する。
図46a乃至46cに、第2テストケースの例を示す。第1テストケースに対応する第2テストケースが生成される。例えば、ケース番号1〜ケース番号4の第2テストケースは、同じ対象内パス条件「P1_cnull==true」を有する。ケース番号1〜ケース番号4は、テスト対象のプログラムの同じルートを通ることを示している。ケース番号1のテストケースで、テスト入力「P1_cnull=true」とテスト入力「P2_cnull=true」を入力して図5に示した対象クラスを実行した場合、「if(obj1!=null)」で偽と判定され、「return 0」で終了するルートを通る。更に、ケース番号2のテストケースで、テスト入力「P1_cnull=true」とテスト入力「P2_cnull=false」とテスト入力「P2_cClass=0」を入力して図5に示した対象クラスを実行した場合にも、同様に「if(obj1!=null)」で偽と判定され、「return 0」で終了するルートを通る。更に、ケース番号3のテストケースで、テスト入力「P1_cnull=true」とテスト入力「P2_cnull=false」とテスト入力「P2_cClass=1」を入力して図5に示した対象クラスを実行した場合にも、同様に「if(obj1!=null)」で偽と判定され、「return 0」で終了するルートを通る。更に、ケース番号4のテストケースで、テスト入力「P1_cnull=true」とテスト入力「P2_cnull=false」とテスト入力「P2_cClass=−1」を入力して図5に示した対象クラスを実行した場合にも、同様に「if(obj1!=null)」で偽と判定され、「return 0」で終了するルートを通る。このようにテスト対象のプログラムの同じルートを通る複数のテストケースは冗長であるので、削減することが望ましい。
図47に、第3テストケースの例を示す。この例では、同じルートを通る複数の第2テストケースのうち、最も小さいケース番号のテストケースを第3テストケースに移し、それ以外は排除している。例えば、ケース番号1〜ケース番号4の第2テストケースのうち、ケース番号1の第2テストケースは第3テストケースセットに移されるが、ケース番号2〜ケース番号4の第2テストケースは第3テストケースセットに移されない。
図48は、テストケース抽出処理フローの例を示す図である。抽出部1037は、第2テストケース毎に以下の処理を繰り返す(S4801)。抽出部1037は、第2テストケースのパス条件と同じパス条件を有する第3テストケースがあるか否かを判定する(S4803)。つまり、抽出部1037は、第2テストケースのパス条件と同じパス条件を有する第3テストケースが第3テストケース記憶部1039に格納されているか否かを判定する。第2テストケースのパス条件と同じパス条件を有する第3テストケースがあると判定した場合には、抽出部1037はS4807へ処理を進める。
第2テストケースのパス条件と同じパス条件を有する第3テストケースがないと判定した場合には、抽出部1037は、第2テストケースを第3テストケースに加える(S4805)。つまり、抽出部1037は、第2テストケースを第3テストケース格納部1039に格納する。抽出部1037は、すべての第2テストケースについて処理したか否かを判定する(S4807)。処理していない第2テストケースがあると判定した場合には、S4801に戻る。すべての第2テストケースについて処理したと判定した場合には、抽出部1037は、第3テストケースセットを出力して(S4809)、終了する。
上述のパス条件更新処理とテストケース抽出処理は、連続して行ってもよく、又は別に行ってもよい。パス条件更新処理とテストケース抽出処理を行うことによって、制御変数を用いたシンボリック実行により高めたコードカバレッジを低下させることなく、テストケースを削減することができる。
以上本技術の一実施の形態を説明したが、本技術はこれに限定されるものではない。例えば、上述の機能ブロック構成は必ずしも実際のプログラムモジュール構成に対応するものではない。
また、上で説明した各記憶領域の構成は一例であって、必ずしも上記のような構成でなければならないわけではない。さらに、処理フローにおいても、処理結果が変わらなければ処理の順番を入れ替えることも可能である。さらに、並列に実行させるようにしても良い。
なお、上で述べたテストケース生成装置は、コンピュータ装置であって、図49に示すように、メモリ2501とCPU(Central Processing Unit)2503とハードディスク・ドライブ(HDD:Hard Disk Drive)2505と表示装置2509に接続される表示制御部2507とリムーバブル・ディスク2511用のドライブ装置2513と入力装置2515とネットワークに接続するための通信制御部2517とがバス2519で接続されている。オペレーティング・システム(OS:Operating System)及び本実施例における処理を実施するためのアプリケーション・プログラムは、HDD2505に格納されており、CPU2503により実行される際にはHDD2505からメモリ2501に読み出される。CPU2503は、アプリケーション・プログラムの処理内容に応じて表示制御部2507、通信制御部2517、ドライブ装置2513を制御して、所定の動作を行わせる。また、処理途中のデータについては、主としてメモリ2501に格納されるが、HDD2505に格納されるようにしてもよい。本技術の実施例では、上で述べた処理を実施するためのアプリケーション・プログラムはコンピュータ読み取り可能なリムーバブル・ディスク2511に格納されて頒布され、ドライブ装置2513からHDD2505にインストールされる。インターネットなどのネットワーク及び通信制御部2517を経由して、HDD2505にインストールされる場合もある。このようなコンピュータ装置は、上で述べたCPU2503、メモリ2501などのハードウエアとOS及びアプリケーション・プログラムなどのプログラムとが有機的に協働することにより、上で述べたような各種機能を実現する。
以上述べた実施の形態をまとめると、以下のようになる。
第1の実施の形態に係るプログラムは、(A)テスト対象のプログラムへ入力されるオブジェクト型変数の状態を示す制御変数を含む一又は複数のシンボル変数を用いて、制御変数に応じたオブジェクト型変数の初期化とテスト対象のプログラムの呼び出しを行うためのドライバ及び呼び出されるテスト対象のプログラムにおける実行パターン毎に、ドライバ及びテスト対象のプログラムの実行において一又は複数のシンボル変数が満たすべき第1のパス条件を計算し、第1のパス条件と第1のパス条件に対する一又は複数のシンボル変数の充足値とを含む第1のテストケースを生成するシンボリック実行処理と、(B)実行パターン毎に、テスト対象のプログラムの実行において状態としてオブジェクト型変数が満たすべき第2のパス条件を生成する第1の生成処理と、(C)実行パターン毎に、第1のテストケースに含まれる第1のパス条件から、制御変数が満たすべき条件を省き、第2のパス条件を加えた第3のパス条件を求め、第3のパス条件と一又は複数のシンボル変数の充足値とを含む第2のテストケースを生成する第2の生成処理と、(D)第3のパス条件が同義である第2のテストケースが複数ある場合に、第3のパス条件が同義である複数の第2のテストケースのうち、いずれかの第2のテストケースを省き、残った第2のテストケースを抽出する抽出処理とをコンピュータに実行させる。
上で述べたようなシンボリック実行処理を実行するので、オブジェクト型変数の状態に関する分岐処理を含むテスト対象のプログラムにおけるテストケースのカバレッジを向上させることができる。
更に、上で述べたようにテストケースを絞り込んでいるので、カバレッジの向上に寄与しないテストケースを排除することができる。つまり、制御変数が満たすべき条件が異なるテストケース同士でも、もしそれらの第2のパス条件が共通であるならば、テスト対象プログラムにおける実行ルートは同じになる。従って、いずれかのテストケースを省くことにより無駄を減らすことができる。
また、上記シンボリック実行処理において、テスト対象のプログラムに含まれる複数の命令のうち、実行すべき命令を特定するようにしてもよい。この場合、上記第1の生成処理において、実行すべき命令に含まれる変数の実体を参照するための位置を特定し、オブジェクト型変数の実体が格納されている位置と参照するための位置が一致する場合に、実行すべき命令に基づいて第2のパス条件を生成するようにしてもよい。
このようにすれば、実行すべき命令に含まれる変数の実体を参照するための位置が、オブジェクト型変数の実体が格納されている位置と一致する場合に、実行すべき命令に基づいて第2のパス条件を生成するので、シンボル変数ではないオブジェクト型変数についてもパス条件を求めることができる。
また、上記シンボリック実行処理において、ドライバに含まれ、且つオブジェクト型変数を含む第1の命令を特定し、更に、第1の命令に基づいてオブジェクト型変数を特定し、特定されたオブジェクト型変数の実体が格納されている位置を特定する特定処理をコンピュータに実行させるようにしてもよい。
このようにすれば、ドライバに含まれる第1の命令に基づいてオブジェクト型変数を特定し、オブジェクト型変数の実体が格納されている位置を特定するので、ドライバから第2のパス条件の生成を指示できるようになる。従って、テスト対象のプログラムに手を加えることを要しない。
また、上記第2の生成処理において、第2のパス条件を制御変数が満たすべき条件の形式に変換するようにしてもよい。
このようにすれば、第2のパス条件を制御変数が満たすべき条件の形式に変換するので、オブジェクト型変数の状態に関する分岐におけるパス条件とシンボル変数の充足値を、ともに制御変数で表すことになり、これらの関係が把握されやすくなる。
上記状態は、オブジェクト型変数がnullであるか否かにより特定されるものであってもよい。
このようにすれば、オブジェクト型変数がnullであるか否かによる分岐を含むプログラムのテストケースを生成することができる。
上記状態は、オブジェクト型変数のクラス型により特定されるものであってもよい。
このようにすれば、オブジェクト型変数のクラス型による分岐を含むプログラムのテストケースを生成することができる。
上記複数のシンボル変数は、オブジェクト型変数のメンバを示すシンボル変数を含んでもよい。
このようにすれば、オブジェクト型変数のメンバによる分岐を含むプログラムのテストケースを生成することができる。
上記複数のシンボル変数は、テスト対象のプログラムへ入力されるプリミティブ型変数を示すシンボル変数を含んでもよい。
このようにすれば、プリミティブ型変数による分岐を含むプログラムのテストケースを生成することができる。
上記抽出処理は、第3のパス条件が同義である複数の第2のテストケースのうち、一つの第2のテストケース以外を省くようにしてもよい。
このようにすれば、テストケースを少なくすることができる。
なお、上記方法による処理をコンピュータに行わせるためのプログラムを作成することができ、当該プログラムは、例えばフレキシブルディスク、CD−ROM、光磁気ディスク、半導体メモリ、ハードディスク等のコンピュータ読み取り可能な記憶媒体又は記憶装置に格納される。尚、中間的な処理結果はメインメモリ等の記憶装置に一時保管される
以上の実施例を含む実施形態に関し、さらに以下の付記を開示する。
(付記1)
テスト対象のプログラムへ入力されるオブジェクト型変数の状態を示す制御変数を含む一又は複数のシンボル変数を用いて、前記制御変数に応じた前記オブジェクト型変数の初期化と前記テスト対象のプログラムの呼び出しを行うためのドライバ及び呼び出される前記テスト対象のプログラムにおける実行パターン毎に、前記ドライバ及び前記テスト対象のプログラムの実行において前記一又は複数のシンボル変数が満たすべき第1のパス条件を計算し、前記第1のパス条件と前記第1のパス条件に対する前記一又は複数のシンボル変数の充足値とを含む第1のテストケースを生成するシンボリック実行処理と、
前記実行パターン毎に、前記テスト対象のプログラムの実行において前記状態として前記オブジェクト型変数が満たすべき第2のパス条件を生成する第1の生成処理と、
前記実行パターン毎に、前記第1のテストケースに含まれる前記第1のパス条件から、前記制御変数が満たすべき条件を省き、前記第2のパス条件を加えた第3のパス条件を求め、前記第3のパス条件と前記一又は複数のシンボル変数の前記充足値とを含む第2のテストケースを生成する第2の生成処理と、
前記第3のパス条件が同義である前記第2のテストケースが複数ある場合に、前記第3のパス条件が同義である複数の前記第2のテストケースのうち、いずれかの前記第2のテストケースを省き、残った前記第2のテストケースを抽出する抽出処理と、
をコンピュータに実行させるためのプログラム。
(付記2)
前記シンボリック実行処理において、前記テスト対象のプログラムに含まれる複数の命令のうち、実行すべき命令を特定し、
前記第1の生成処理において、前記実行すべき命令に含まれる変数の実体を参照するための位置を特定し、前記オブジェクト型変数の実体が格納されている位置と前記参照するための位置が一致する場合に、前記実行すべき命令に基づいて前記第2のパス条件を生成する
付記1記載のプログラム。
(付記3)
前記シンボリック実行処理において、前記ドライバに含まれ、且つ前記オブジェクト型変数を含む第1の命令を特定し、
更に、前記第1の命令に基づいて前記オブジェクト型変数を特定し、特定された前記オブジェクト型変数の前記実体が格納されている前記位置を特定する特定処理をコンピュータに実行させる
付記2記載のプログラム。
(付記4)
前記第2の生成処理において、前記第2のパス条件を前記制御変数が満たすべき条件の形式に変換する
付記1乃至3のいずれか1つ記載のプログラム。
(付記5)
前記状態は、前記オブジェクト型変数がnullであるか否かにより特定される
付記1乃至4のいずれか1つ記載のプログラム。
(付記6)
前記状態は、前記オブジェクト型変数のクラス型により特定される
付記1乃至4のいずれか1つ記載のプログラム。
(付記7)
前記複数のシンボル変数は、前記オブジェクト型変数のメンバを示すシンボル変数を含む
付記1乃至6のいずれか1つ記載のプログラム。
(付記8)
前記複数のシンボル変数は、前記テスト対象のプログラムへ入力されるプリミティブ型変数を示すシンボル変数を含む
付記1乃至7のいずれか1つ記載のプログラム。
(付記9)
前記抽出処理は、前記第3のパス条件が同義である前記複数の第2のテストケースのうち、一つの前記第2のテストケース以外を省く
付記1乃至8のいずれか1つ記載のプログラム。
(付記10)
テスト対象のプログラムへ入力されるオブジェクト型変数の状態を示す制御変数を含む一又は複数のシンボル変数を用いて、前記制御変数に応じた前記オブジェクト型変数の初期化と前記テスト対象のプログラムの呼び出しを行うためのドライバ及び呼び出される前記テスト対象のプログラムにおける実行パターン毎に、前記ドライバ及び前記テスト対象のプログラムの実行において前記一又は複数のシンボル変数が満たすべき第1のパス条件を計算し、前記第1のパス条件と前記第1のパス条件に対する前記一又は複数のシンボル変数の充足値とを含む第1のテストケースを生成するシンボリック実行処理と、
前記実行パターン毎に、前記テスト対象のプログラムの実行において前記状態として前記オブジェクト型変数が満たすべき第2のパス条件を生成する第1の生成処理と、
前記実行パターン毎に、前記第1のテストケースに含まれる前記第1のパス条件から、前記制御変数が満たすべき条件を省き、前記第2のパス条件を加えた第3のパス条件を求め、前記第3のパス条件と前記一又は複数のシンボル変数の前記充足値とを含む第2のテストケースを生成する第2の生成処理と、
前記第3のパス条件が同義である前記第2のテストケースが複数ある場合に、前記第3のパス条件が同義である複数の前記第2のテストケースのうち、いずれかの前記第2のテストケースを省き、残った前記第2のテストケースを抽出する抽出処理と、
を含みコンピュータが実行するテストケース生成方法。
(付記11)
テスト対象のプログラムへ入力されるオブジェクト型変数の状態を示す制御変数を含む一又は複数のシンボル変数を用いて、前記制御変数に応じた前記オブジェクト型変数の初期化と前記テスト対象のプログラムの呼び出しを行うためのドライバ及び呼び出される前記テスト対象のプログラムにおける実行パターン毎に、前記ドライバ及び前記テスト対象のプログラムの実行において前記一又は複数のシンボル変数が満たすべき第1のパス条件を計算し、前記第1のパス条件と前記第1のパス条件に対する前記一又は複数のシンボル変数の充足値とを含む第1のテストケースを生成するシンボリック実行を行う実行部と、
前記実行パターン毎に、前記テスト対象のプログラムの実行において前記状態として前記オブジェクト型変数が満たすべき第2のパス条件を生成する第1の生成部と、
前記実行パターン毎に、前記第1のテストケースに含まれる前記第1のパス条件から、前記制御変数が満たすべき条件を省き、前記第2のパス条件を加えた第3のパス条件を求め、前記第3のパス条件と前記一又は複数のシンボル変数の前記充足値とを含む第2のテストケースを生成する第2の生成部と、
前記第3のパス条件が同義である前記第2のテストケースが複数ある場合に、前記第3のパス条件が同義である複数の前記第2のテストケースのうち、いずれかの前記第2のテストケースを省き、残った前記第2のテストケースを抽出する抽出部と、
を有するテストケース生成装置。