以下、図面を参照して本発明の実施例について説明する。
本発明の実施例では、プログラムのテストシナリオ及びテストデータの組み合わせであるテストケースを生成するテストケース生成プログラム及びテストケース生成方法について説明する。なお、テストケース生成プログラムに関する説明の便宜上、プログラムの各機能をコンピュータ上に実現したテストケース生成装置を例に挙げて説明する。
以下の実施例ではテストシナリオの生成から説明するが、本発明の実施例は、テストシナリオが指定されたときに、指定のテストシナリオに対するテストデータを生成するテストデータ生成プログラム及びテストデータ生成方法としても実現できる。
テストケース生成装置は、Webアプリケーションのようなユーザインタフェースをもつアプリケーションのプログラムをテスト対象として、テストシナリオを生成する。このようなアプリケーションは、MVC(Model View Controller)に従って設計され、少なくともView及びControllerで構成される。Modelは、アプリケーションが扱うデータ及びロジックを表現するための要素であり、Viewは、入出力や表示を行うための要素であり、Controllerは、Viewからの入力に応じて必要なロジックの実行をModelに依頼し、その結果表示をViewに依頼するための要素である。MVCに従って設計されたプログラムでは、Controllerの情報を用いてView間の繋がりが抽出できる。テストケース生成装置は、View間の繋がりを表すViewの遷移図から状態遷移図に対する所定のカバレッジ基準に基づいてView及びControllerの繋がりを表すVCシナリオを生成する。
テストケース生成装置は、生成されたVCシナリオを満たすようなテストデータを、テスト対象のプログラムを動かしながら生成する。一方、ViewとControllerの名前の羅列から構成されるVCシナリオの情報だけでは、どういった操作を行えば良いかわからない。そこで、テストケース生成装置は、クローラやユーザ操作等によってVCシナリオにView操作情報を加えることで、テストシナリオを生成する。
次に、テストケース生成装置は、生成されたテストシナリオのうち1つのシナリオを指定して、以下のようにテストデータを生成する。
テストケース生成装置は、テストデータを生成するために、入力値を記号に置き換えて得られた制約式を解析することによりテストデータを生成する第1テストデータ生成手法と、分岐に対する評価値を解析することによりテストデータを生成する第2テストデータ生成手法という性質の異なる2つの手法を組み合わせてテストデータを生成する。
第1テストデータ生成手法の具体例は、Concolic Testingである。Concolic Testingとは、入力値を記号に置き換えて得られた制約式を解析することによりテストデータを生成するテストデータ生成手法である。例えば、入力値>0という分岐に対して具体的な数値を用いる代わりに、数値を記号xに置き換えてx>0という制約式を解析することにより、分岐条件を満たすテストデータを生成する。
第2テストデータ生成手法の具体例は、SBSTである。SBSTとは、分岐の判定を定量的に評価するための評価値を解析することによりテストデータを生成するテストデータ生成手法である。例えば、入力値>0という分岐に対して(0-入力値)という評価関数を設計し、評価関数の評価値を解析することで、分岐条件を満たすテストデータを生成する。
以下では、Concolic Testing及びSBSTを用いた具体例を説明する。
テストケース生成装置は、はじめにConcolic Testingを実行し、テストデータを生成する。Concolic Testingの実行の前に、テスト対象のプログラムに、分岐の判定を定量的に評価するための評価値を含む分岐結果を出力するコードを挿入しておき、Concolic Testingの実行時に、テストデータを生成すると共に、挿入されたコードが出力した分岐結果を生成する。次に、テストケース生成装置は、Concolic Testingで生成したテストデータが通過することのできない分岐に対してSBSTを実行することでカバレッジを向上させるテストデータを生成する。Concolic Testing実行時に生成されたテストデータ及び分岐結果を用いることで、SBSTによる効率的なテストデータの探索が可能になる。
ただし、結合テスト対象となる規模のソースコードに対し、Concolic TestingやSBSTを行うと計算爆発が起きるため、指定されたユーザ記述クラスを解析対象としてテストデータを生成してもよい。すなわち、フレームワークやライブラリ等のユーザが記述していない箇所に対しては、カバレッジを向上させるようなテストケースを生成しないことで、計算爆発を回避してもよい。
最後に、テストケース生成装置は、テストシナリオ及びテストデータの組み合わせであるテストケースを出力する。
<用語の説明>
まず、本発明の実施例において用いられる用語について説明する。
テストスイートとは、複数のテストケースと、それぞれのテストケースを実行したときの分岐結果から構成される。本発明の実施例における最終的な出力となるテストケースとそのテストケースの分岐結果から構成されるテストスイートを出力テストスイートと呼び、SBSTを実行するために用いられるテストスイートを素材テストスイートと呼ぶ。例えば、テストスイートは、[テストケース1,分岐結果1],[テストケース2,分岐結果2],…として定義される。
テストケースとは、プログラムのテストを実行するために必要な情報を所持しているものであり、1つのテストシナリオと1つのテストデータから構成される。
テストシナリオとは、テストを実行するための手順を表し、VCシナリオとView操作情報であるステップの集合から構成される。例えば、テストシナリオは、[VCシナリオ],[ステップ1,ステップ2,…]として定義される。
テストデータとは、テストシナリオを実現するための具体的な値の集合である。SBSTにおいて、この具体的な値を求めるために遺伝的アルゴリズムが用いられる場合、テストデータは、遺伝子の集合と考えられる。便宜上、Concolic Testing等が用いられる場合であっても、テストデータを遺伝子の集合として定義する。例えば、テストデータは、遺伝子1,遺伝子2, …として定義される。
Viewの遷移図とは、View間の繋がりを表した遷移図である。MVCに従って設計されたプログラムでは、ControllerはViewからの入力をModelに伝え、Modelの実行結果をViewに伝えるため、Controllerの情報を用いてView間の繋がりであるViewの遷移図が生成できる。
VCシナリオとは、Viewの遷移図から生成されるView名及びController名の羅列である。VCシナリオは、View名で始まり、View名で終わる。例えば、VCシナリオは、View名→Controller名→View名→…→View名として定義される。
ステップとは、テストを実行するための手順であるテストシナリオの最小単位を表し、Webアプリケーションである場合には、htmlにおけるフォームやボタンに付与されるidと、動作を示すprocから構成される。
遺伝子とは、テストデータの各要素を表し、Webアプリケーションである場合には、htmlにおけるフォームのidと、具体的な値であるvalueから構成される。
例えば、View1においてIDとPWを入力して、transmitというidが付与されている「ログイン」ボタンを押下するWebアプリケーションをテストする例を考える。この例では、1つのテストケースは、以下のテストシナリオとテストデータの組み合わせで構成される。
テストシナリオ:
VCシナリオ:View1→Controller1→…
ステップ1:id="ID", proc="入力"
ステップ2:id="PW", proc="入力"
ステップ3:id="transmit", proc="押下"
…
テストデータ:
遺伝子1:id="ID", value="aaaa"
遺伝子2:id="PW", value="1234"
…
すなわち、このテストケースは、(1)View1においてid="ID"となっているフォームに"aaaa"を入力し、(2)id="PW"となっているフォームに"1234"を入力し、(3)id="transmit"となっているボタンを押下することを意味する。
分岐結果は、テストケースを実行したときのコード上の各分岐の結果である分岐結果要素から構成される。例えば、分岐結果は、分岐結果要素1,分岐結果要素2,…として定義される。
分岐結果要素は、判定分岐、判定順番、判定結果、及び評価値から構成される。判定分岐は、判定対象の分岐を示し、すなわち、どの分岐を判定したかを表す。判定順番は、判定分岐がプログラムの中の全分岐の中で何番目に判定されたかを表す。判定結果は、判定分岐の判定結果(True/False)を表す。評価値は、分岐の判定を定量的に表す値を表す。
評価値について更に具体的に説明する。評価値は、分岐条件を満たしている度合い又は分岐条件を満たしていない度合いを表し、判定分岐に対して設定された評価関数によって取得できる。例えば、if(x>0)という分岐がある場合、x=1の場合とx=100の場合では同じTrueを返すが、x=100の時の方がx=1の時と比べて0より大きいため、より分岐条件を満たしている度合いは強いと評価することができる。分岐条件を満たしている場合には評価値は負の値を持ち、満たしていない場合には正の値を持つ。評価関数は、分岐に対して設定され、例えば、分岐条件がa==bである場合、評価関数はabs(a-b)として定義されてもよく、分岐条件がa!=bである場合、評価関数は-abs(a-b)として定義されてもよく、分岐条件がa<b又はa<=bである場合、評価関数はa-bとして定義されてもよく、分岐条件がa>b又はa>=bである場合、評価関数はb-aとして定義されてもよい。
最終分岐結果要素とは、ある分岐結果の分岐結果要素のうち、判定順番の値が最も大きい値を持つ分岐結果要素を示す。また、最終分岐結果要素を除いた分岐結果の集合を途中分岐結果と定義する。最終分岐結果要素の判定分岐、判定順番、判定結果、及び評価値を、それぞれ最終判定分岐、最終判定順番、最終判定結果及び最終評価値と定義する。
図1に、分岐結果の例を示す。判定分岐が分岐a、分岐b、分岐cである3つの分岐結果要素から構成される分岐結果αを例に挙げると、最終分岐結果要素は分岐cの分岐結果要素である[c,3,True,-2]であり、途中分岐結果は、分岐a及び分岐bの分岐結果要素である[a,1,True,-1],[b,2,False,1]である。
経路一致とは、分岐結果Aと分岐結果Bが存在するとき、分岐結果Aの各分岐結果要素が全て、分岐結果Bの分岐結果要素のいずれかと、評価値を除いて一致している場合、分岐結果Aは分岐結果Bに対して経路一致していると定義する。
図1に示す分岐結果α、分岐結果β、及び分岐結果γを例に挙げると、分岐結果αの分岐結果要素は、分岐結果βの分岐結果要素のいずれかと、評価値を除いて一致しているため、分岐結果αは分岐結果βに対して経路一致している。また、分岐結果αの分岐結果要素は、分岐結果γのいずれかと、評価値を除いて一致していないため、分岐結果αは分岐結果γに対して経路一致していない。
カバレッジとは、プログラムのソースコードがテストされた割合を示す。単位は%である。カバレッジの基準は複数存在し、例えば、分岐網羅率及び条件網羅率が存在するが、特に明記しない限り、本発明の実施例では分岐網羅率をカバレッジと呼ぶ。カバレッジの高いテストデータの集合のことを網羅的なテストデータ又は網羅性の高いテストデータと呼ぶ。
図2に、分岐網羅率と条件網羅率との関係を示す。分岐網羅率は、C1カバレッジとも呼ばれ、プログラム内の分岐がテストされた割合を示す。例えば、図2のような2つの分岐A及び分岐Bが存在するプログラムにおいてC1カバレッジを100%とするためには、分岐A=False且つ分岐B=Trueの場合と、分岐A=True且つ分岐B=Falseの場合の2つをテストする必要がある。
また、条件網羅率は、C2カバレッジとも呼ばれ、プログラム内の条件がテストされた割合を示す。例えば、図2のような2つの分岐A及び分岐Bが存在するプログラムにおいてC2カバレッジを100%とするためには、分岐A=False且つ分岐B=Trueの場合と、分岐A=True且つ分岐B=Falseの場合と、分岐A=True且つ分岐B=Trueの場合と、分岐A=False且つ分岐B=Falseの場合の4つをテストする必要がある。
<テストケース生成装置の構成>
次に、本発明の実施例に係るテストケース生成装置の構成について説明する。図3は、本発明の実施例に係るテストケース生成装置100の機能ブロック図である。
テストケース生成装置100は、CPU(Central Processing Unit)等のプロセッサ、RAM(Random Access Memory)やROM(Read Only Memory)等のメモリ装置、ハードディスク等の記憶装置等から構成されたコンピュータでもよい。例えば、テストケース生成装置の機能及び処理は、記憶装置又はメモリ装置に格納されているデータやプログラムをプロセッサが実行することによって実現されてもよい。
テストケース生成装置100は、ソースコードを入力とし、テストシナリオ及びテストデータの組み合わせであるテストケースを出力する。
テストケース生成装置100は、VCシナリオ生成部101と、テストシナリオ生成部103と、テストデータ生成部105とを有する。なお、本発明の実施例は、VCシナリオ生成部101及びテストシナリオ生成部103を含まず、テストデータ生成部105を含むテストデータ生成装置として実現されてもよい。例えば、処理フロー図等から生成されたテストシナリオが指定され、テストデータ生成装置が指定のテストシナリオに対するテストデータを生成してもよい。
VCシナリオ生成部101は、MVCに従って設計されたアプリケーションのプログラムをテスト対象としたときに、ソースコード内のControllerの情報を用いてViewの遷移図を生成する。図4の左側にViewの遷移図の例を示す。遷移図は、状態と、状態同士の関連性を表す線である遷移で構成される。ソースコードにおけるViewは1つの状態と考えられ、Controllerも1つの状態と考えられる。ControllerはViewからの入力をModelに伝え、Modelの実行結果をViewに伝えるため、Controllerの情報を用いてView間の繋がりであるViewの遷移図が抽出できる。更に、VCシナリオ生成部101は、Viewの遷移図から状態遷移図に対する所定のカバレッジ基準に基づいてView及びControllerの繋がりを表すVCシナリオを生成する。図4の左側に示すように、Controller1、Controller2、Controller3によってView1、View2、View3の繋がりであるViewの遷移図が生成できると、図4の右側に示すように、1つのView名から始まり1つのView名で終わる複数のVCシナリオが生成できる。VCシナリオの数は状態の数によって膨大な数となるため、状態遷移図に対する所定のカバレッジ基準に基づいてVCシナリオを生成する。
図5は、状態遷移図に対するカバレッジ基準を示す図である。例えば、状態遷移図に対する所定のカバレッジ基準として、All-states、All-transitions、All-transition-pairs、All-loop-free-paths、All-one-loop-paths、All-paths等が存在する。All-statesとは、全状態がどこかのシナリオに含まれるという基準である。例えば、図5に示す状態遷移図を例に挙げると、状態A→状態B→状態D→状態E→状態B→状態Cのシナリオは、All-statesを満たす。All-transitionsとは、全ての長さが1以下のシナリオ(1遷移)がカバーされるという基準である。例えば、図5に示す状態遷移図を例に挙げると、状態A→状態B、状態B→状態C、状態B→状態D、状態D→状態E、状態E→状態Bのシナリオは、All-transitionsを満たす。All-transition-pairsとは、全ての長さが2以下のパス(遷移ペア)がカバーされるという基準である。例えば、図5に示す状態遷移図を例に挙げると、All-transitionsを満たすシナリオに加えて、状態A→状態B→状態C、状態A→状態B→状態D、状態B→状態D→状態E、状態D→状態E→状態B、状態E→状態B→状態D、状態E→状態B→状態Cのシナリオは、All-transition-pairsを満たす。All-loop-free-pathsとは、同じ状態が2回以上現れず、且つ、他のシナリオに部分的に含まれないようなシナリオ(prime pathと呼ばれる)が全てカバーされるという基準である。なお、All-loop-free-pathsはAll-transitionsを保証するものではない。例えば、図5に示す状態遷移図を例に挙げると、状態A→状態B→状態C、状態A→状態B→状態D→状態Eのシナリオは、All-loop-free-pathsを満たす。All-one-loop-pathsとは、All-loop-free-pathsに加えて、ループ1つのみを1回だけ回るシナリオがカバーされるという基準である。例えば、図5に示す状態遷移図を例に挙げると、状態A→状態B→状態C、状態A→状態B→状態D→状態E→状態B→状態Cのシナリオは、All-one-loop-pathsを満たす。All-pathsとは、全てのシナリオがカバーされるという基準である。なお、通常はループが存在するため、All-pathsを満たすシナリオは無限通り存在するため、有用ではない。
テストシナリオ生成部103は、生成されたVCシナリオにView操作情報を追加する。例えば、クローラやユーザ操作等によって、生成されたVCシナリオを満たすようなView操作情報を追加する。View操作情報は、ステップの集合で表される。具体的には、クローラやユーザ操作等によってテスト対象のプログラムを動かすことで、テストシナリオ生成部103は、生成されたVCシナリオと同じ遷移をするView操作情報を取得すると共に、View操作情報を取得したときのテストデータである初期テストデータを取得する。テストシナリオ生成部103は、VCシナリオにView操作情報及び初期テストデータを追加した初期テストケースを生成する。
テストデータ生成部105は、生成されたテストシナリオのうち1つのシナリオを指定して、Concolic TestingとSBSTという性質の異なる2つの手法を組み合わせてテストデータを生成する。テストデータ生成部105は、コード挿入部111と、Concolic Testing部113と、SBST部115とを有する。
コード挿入部111は、テスト対象のプログラムに、分岐の判定を定量的に評価するための評価値を含む分岐結果を出力するコードを挿入する。このように、コード挿入部111は、Concolic Testingを実行している間にSBSTで必要な情報を予め取得するためのコードを挿入する。コード挿入部111は、解析対象のユーザ記述クラス内における分岐の箇所に、分岐結果を出力するコードを挿入してもよい。コード挿入部111は、解析対象のユーザ記述クラスに対しては、プログラムの分岐を解析するためのコードを挿入してもよいが、フレームワークやライブラリ等のユーザが記述していない箇所は解析対象外とし、プログラムの分岐を解析するためのコードを挿入しなくてもよい。
Concolic Testing部113は、入力値を記号に置き換えて得られた制約式を解析することによりテストデータを生成すると共に、挿入されたコードが出力した分岐結果を生成する。このように、Concolic Testing部113は、テストデータを生成している間に、SBSTで必要な情報である分岐結果を収集する。すなわち、Concolic Testing部113は、指定のテストシナリオに対してテストデータを生成する過程において、指定のテストシナリオと当該テストデータと分岐結果とを、SBSTを実行するために用いられる素材テストスイートに追加する。素材テストスイートには、経路一致している分岐結果が存在する可能性があるため、Concolic Testing部113は、指定のテストシナリオに対して生成されたテストデータによってカバレッジが向上する場合、指定のテストシナリオと当該テストデータと分岐結果とを出力テストスイートに追加する。
SBST部115は、Concolic Testingで生成したテストデータが通過することのできない分岐に対してSBSTを実行することでカバレッジを向上させるテストデータを生成する。具体的には、SBST部115は、Concolic Testing部113において生成されたテストデータ及び分岐結果に基づいて、分岐に対する評価値を解析することによりテストデータを生成する。SBST部115は、出力テストスイートの分岐結果に対して途中まで経路一致する目標分岐結果を生成し、目標分岐結果と経路一致するテストデータが出力テストスイートに存在しない場合、素材テストスイートを用いて目標分岐結果を満たすテストデータを生成し、出力テストスイートに追加する。
SBST部115は、テストデータを生成するために遺伝的アルゴリズムを用いてもよい。遺伝的アルゴリズムの選択、交叉、及び突然変異をそれぞれ実施するため、SBST部115は、選択部121と、交叉部123と、突然変異部125とを含んでもよい。遺伝的アルゴリズムを用いて効果的にテストデータを生成するため、SBST部115は、素材テストスイートの分岐結果を、目標分岐結果の最終判定分岐を持つ分岐結果要素の評価値でソートし、ソートされた素材テストスイートから順にテストケースを選択し、選択したテストケースの遺伝子を選択部121、交叉部123、及び突然変異部125によって操作することにより、テストデータを生成してもよい。
<テストケース生成方法の手順>
次に、本発明の実施例に係るテストケース生成方法について説明する。図6は、本発明の実施例に係るテストケース生成方法のフローチャートである。
まず、ステップS001において、VCシナリオ生成部101は、テスト対象のプログラムのソースコードを入力として受け取り、ソースコード内のControllerの情報を用いて、View間の繋がりを表すViewの遷移図を生成する。
ステップS001について図7を参照して更に説明する。
ステップS101において、VCシナリオ生成部101は、テスト対象のプログラムのソースコードを入力として受け取り、ソースコード内のViewを抽出する。
ステップS102において、VCシナリオ生成部101は、テスト対象のプログラムのソースコードを入力として受け取り、Controllerの情報を用いてView間の繋がりを検出する。具体的には、VCシナリオ生成部101は、抽出されたViewの1つを対象Viewとして選択し、対象View名で指定されたViewの遷移先のControllerを取得する。そして、取得した遷移先のControllerの遷移先のViewを対象Viewの遷移先のViewとする。ステップS101で抽出した各Viewに上記の処理を繰り返すことで、各対象Viewの全ての遷移先のView名と、これらの間に存在するController名が出力される。
ステップS103において、VCシナリオ生成部101は、各対象Viewの全ての遷移先のView名と、これらの間に存在するController名を入力として受け取り、Viewの遷移図を作成する。Viewの遷移図には、View名だけでなく、Controller名も記録される。Viewの遷移図が生成された場合、図6のステップS002に戻る。
次に、図6のステップS002において、VCシナリオ生成部101は、Viewの遷移図を入力として受け取り、Viewの遷移図に対して、状態遷移図に対する所定のカバレッジ基準に基づいてVCシナリオを生成する。
ステップS002について図8を参照して更に説明する。
ステップS104において、VCシナリオ生成部101は、Viewの遷移図を状態遷移図として扱い、All-states等の状態遷移図に対する所定のカバレッジ基準に基づいて、複数のVCシナリオを作成する。VCシナリオが生成された場合、図6のステップS003に戻る。
次に、図6のステップS003において、テストシナリオ生成部103は、VCシナリオを入力として受け取り、各VCシナリオに対してVCシナリオを満たすテストケースを、クローラ等の技術を用いて生成する。そして、VCシナリオを実現するテストシナリオ及びテストデータを1件のテストケース(初期テストケース)として出力する。
ステップS003について図9を参照して更に説明する。
ステップS105において、テストシナリオ生成部103は、テスト対象のプログラムとVCシナリオを入力として受け取り、クローラ等によってテスト対象のプログラムを実際に操作し、VCシナリオの先頭のViewが表すhtmlファイルにアクセスするURLに移動する。なお、テスト対象のプログラムの操作は、クローラ等の他にユーザによる操作でも代用可能である。
ステップS106において、テストシナリオ生成部103は、空のテストケースTC0を作成する。空のテストケースTC0には、テストシナリオであるVCシナリオとステップの集合の具体的な値は入っておらず、テストデータも入っていない。
ステップS107において、テストシナリオ生成部103は、テスト対象のプログラムとテストケースTC0を入力として受け取り、クローラ等によってテスト対象のプログラムを実際に操作し、テスト対象のプログラムを操作したときに入力したフォームのidやその値をテストケースTC0のテストデータに追加し、入力したフォームのidや押下したボタンのid等をテストケースTC0のテストシナリオに追加する。なお、テスト対象のプログラムの操作は、クローラ等の他にユーザによる操作でも代用可能である。また、操作中のViewやControllerの遷移も取得し、テストケースTC0のテストシナリオに追加する。新しいViewに遷移したところで次のステップS108に移行する。
ステップS108において、テストシナリオ生成部103は、テストケースTC0とVCシナリオを入力として受け取り、VCシナリオのView及びControllerの遷移と、テストケースTC0が途中又は最後まで同じ遷移をしているか否かを判断する。同じ遷移をしていない場合、ステップS109に移行し、同じ遷移をしている場合、ステップS110に移行する。
ステップS109において、テストシナリオ生成部103は、テストケースTC0を入力として受け取り、VCシナリオの遷移とテストケースTC0の遷移が異なる場合、テストケースTC0はVCシナリオを満たさないため、テストケースTC0を破棄し、ステップS105に移行する。
ステップS110において、テストシナリオ生成部103は、テストケースTC0とVCシナリオを入力として受け取り、VCシナリオのView及びControllerの遷移と、テストケースTC0が最後まで同じ遷移をしているか否かを判断する。最後まで同じ遷移をしていない場合、すなわち、途中までは同じ遷移をしているが、最後まで同じ遷移をしていない場合には、更にテスト対象のプログラムを操作する必要があるため、ステップS107に移行する。同じ遷移をしている場合、ステップS111に移行する。
ステップS111において、テストシナリオ生成部103は、テストケースTC0を入力として受け取り、テストケースTC0を初期テストケースとして出力する。初期テストケースが出力された場合、図6のステップS005に戻る。
次に、図6のステップS005において、テストデータ生成部105のコード挿入部111は、テスト対象のプログラムのバイトコードを入力として受け取り、ユーザ記述クラス内のメソッド上のバイトコードに対して、テストデータ生成に必要な情報を取得するためのコードを挿入する。なお、バイトコードの代わりにソースコードを入力として受け取ってもよい。Concolic Testingでは、入力値を記号に置き換えて得られた制約式を解析する必要があるため、入力値を記号に置き換えるためのコードを挿入する。また、コード挿入部111は、Concolic Testingを実行している間にSBSTで必要な情報を予め取得するためのコードを挿入する。SBSTでは、分岐の評価値を解析する必要があるため、分岐に対する評価関数の値を出力するためのコードを挿入する。コード挿入部111は、ユーザ記述クラスにコード挿入されたバイトコードを出力する。
なお、コード挿入部111は、解析対象のユーザ記述クラス名を入力として受け取ってもよく、解析対象外のユーザ記述クラス名を入力として受け取ってもよい。解析対象のユーザ記述クラス名及び解析対象外のユーザ記述クラス名は、ネームスペースで指定されてもよい。この場合、コード挿入部111は、解析対象のユーザ記述クラス内のメソッド上のバイトコードに対して、テストデータ生成に必要な情報を取得するためのコードを挿入する。
ステップS005について図10を参照して更に説明する。
ステップS112において、コード挿入部111は、ユーザにより入力された解析対象のユーザ記述クラス名を入力として受け取ってもよい。また、コード挿入部111は、ユーザにより入力された解析対象外のユーザ記述クラス名を入力として受け取ってもよい。ユーザ記述クラス名がネームスペースで指定された場合、コード挿入部111は、指定されたネームスペースを持つクラスの名前をバイトコードを調べて取得する。ただし、解析対象外のユーザクラス名が存在する場合、コード挿入部111は、解析対象外のユーザクラス名を持つユーザ記述クラスを除外する。
ステップS113において、コード挿入部111は、解析対象のユーザ記述クラス内のメソッド上のバイトコードの各行を調べ、テストデータ生成に必要な情報を取得するためのコードを挿入する。コード挿入部111は、Concolic Testingで必要な情報を取得するために、解析対象のユーザ記述クラス内における入力値に対する演算が施される行及び分岐の行に、入力値を記号に置き換えるためのコードを挿入する。また、コード挿入部111は、SBSTで必要な情報を取得するために、解析対象のユーザ記述クラス内における分岐の箇所に、分岐結果を出力するコードを挿入する。ユーザ記述クラス内のメソッド上でコードを挿入する必要がない行に対しては何も実施しない。コードが挿入された場合、図6のステップS006に戻る。
次に、初期テストケースの中から1つのテストケースを指定し、以下のようにテストデータを生成する。
図6のステップS006において、テストデータ生成部105のConcolic Testing部113は、空の出力テストスイートを作成する。空の出力テストスイートには、テストシナリオであるVCシナリオとステップの集合の具体的な値は入っておらず、テストデータも分岐結果も入っていない。
次に、図6のステップS007において、Concolic Testing部113は、コード挿入されたバイトコードと、初期テストケースと、出力テストスイートを入力として受け取り、初期テストケースに基づき、Concolic Testingに従ってテストデータを生成し、得られたテストケースを出力テストスイートに追加する。
ステップS007について図11を参照して更に説明する。
ステップS114において、Concolic Testing部113は、初期テストケースを入力として受け取り、初期テストケースを複製してテストケースTCNと定義する。
ステップS115において、Concolic Testing部113は、テストケースTCN及びコード挿入されたバイトコードを入力として受け取り、Concolic Testingに従って新しいテストデータを生成する。Concolic Testingでは、テストケースTCNを実際に実行する必要があるが、テストケースTCNにはView操作情報を含むテストシナリオや、具体的なテストデータが含まれているため、スクリプトを作成し、スクリプトを実行するツールであるSelenium等を利用することにより自動的にConcolic Testingを実行することができる。また、コード挿入部111によってSBSTで必要な情報である分岐結果を出力するコードが挿入されているため、Concolic Testing部113は、テストデータと共に分岐結果を取得することができる。
ステップS116において、Concolic Testing部113は、生成したテストデータと初期テストケースを入力として受け取り、生成したテストデータを初期テストケースの中のテストデータと置き換えて、新しいテストケースTCNを出力する。
ステップS117において、Concolic Testing部113は、テストケースTCNと分岐結果と素材テストスイートを入力として受け取り、テストケースTCNと分岐結果を素材テストスイートに追加する。
ステップS118において、Concolic Testing部113は、テストケースTCNと出力テストスイートを入力として受け取り、テストケースTCNを出力テストスイートに加えることでカバレッジが向上するか否かを判断する。カバレッジが向上する場合、ステップS119に移行し、カバレッジが向上しない場合、ステップS120に移行する。
ステップS119において、Concolic Testing部113は、テストケースTCNと分岐結果と出力テストケースを入力として受け取り、テストケースTCNと分岐結果を出力テストスイートに追加する。
ステップS120において、Concolic Testing部113は、解析が終わっていない場合、ステップS115に移行し、テストデータの生成を繰り返す。解析が終わった場合、図6のステップS008に戻る。
次に、図6のステップS008において、テストデータ生成部105のSBST部115は、SBSTで必要な情報である分岐結果を出力するコードが挿入されたバイトコードと出力テストスイートと素材テストスイートを入力として受け取る。SBST部115は、コードが挿入されたバイトコードに対し、テストデータの各遺伝子を入力としてテスト対象のプログラムを実際に動かして解析するSBSTを実行し、Concolic Testing部113で生成したテストデータが通過することのできない分岐を通過するようなテストデータを生成する。SBST部115は、このようにカバレッジを向上させるテストデータを出力テストスイートに追加して出力テストスイートを強化する。なお、SBST部115で用いるテストデータは、素材テストスイートから選択される。
ステップS008について図12を参照して更に説明する。
ステップS201において、SBST部115は、出力テストスイートの各分岐結果BR0に対して、分岐結果BR0の分岐結果要素の数をnとする。
ステップS202において、SBST部115は、分岐結果BR0を入力として受け取り、分岐結果BR0に対し、判定順番の値がnより大きい分岐結果要素を全て削除した新しい分岐結果BRを作成する。
ステップS203において、SBST部115は、分岐結果BRを入力として受け取り、分岐結果BRに対し、最終判定結果を反転した新しい分岐結果を作成し、目標分岐結果とする。例えば、分岐結果BRの最終判定結果がTrueである場合、その最終判定結果をFalseとし、分岐結果BRの最終判定結果がFalseである場合、その最終判定結果をTrueとする。
ステップS204において、SBST部115は、目標分岐結果と経路一致する分岐結果が出力テストスイートに存在するか否かを判断する。図1を参照して説明した通り、ここでは分岐結果の経路一致を判断するため、評価値は異なってもよい。目標分岐結果と経路一致する分岐結果が出力テストスイートに存在しない場合、ステップS205に移行し、存在する場合、ステップS206に移行する。
ステップS205において、SBST部115は、素材テストスイートと目標分岐結果を入力として受け取り、目標分岐結果を満たすようなテストデータをSBSTによって生成する。
ステップS205について、図13を参照して更に説明する。
ステップS301において、遺伝的アルゴリズムを用いてSBSTを実行するときの最大世代数をGとし、現在の世代gを1とする。
ステップS302において、SBST部115は、素材テストスイートと目標分岐結果を入力として受け取り、素材テストスイートの各分岐結果に対し、目標分岐結果の最終判定分岐を持つ分岐結果要素の評価値でソートする。例えば、目標分岐結果の最終判定分岐がTrueである場合、評価値の値が小さいほど優秀であると判断し、目標分岐結果の最終判定分岐がFalseである場合、評価値の値が大きいほど優秀であると判断する。ただし、目標分岐結果の最終判定分岐を持たない分岐結果要素は、最も優秀でないと判断する。SBST部115は、優秀であると判断された分岐結果と、それに対応するテストケースを上から順番に並べてソートする。
ステップS303において、SBST部115は、空のテストスイートTSを生成する。空のテストスイートTSには、テストケースの具体的な値は入っておらず、分岐結果も入っていない。
ステップS304において、SBST部115の選択部121は、ソートされた素材テストスイートとテストスイートTSとを入力として受け取り、ソートされた素材テストスイートの上から順番に複数のテストケースを選択する。選択されるテストケースの個数は、予め決められた定数とする。選択部121は、選択されたテストケースの遺伝子を操作したテストケースを生成する。例えば、選択部121は、選択されたテストケースが持つ1つの遺伝子に対し、int型であればランダムで1を加えてもよく、1を引いてもよい。例えば、選択部121は、選択されたテストケースが持つ1つの遺伝子に対し、String型であればランダムで1文字を追加してもよく、1文字を削除してもよい。選択部121は、この動作を全ての遺伝子に対して実施することで、1つのテストケースに対し、遺伝子の数だけ新しいテストケースを生成し、新しいテストケースをテストスイートTSに追加する。
ステップS305において、SBST部115の交叉部123は、ソートされた素材テストスイートとテストスイートTSとを入力として受け取り、ソートされた素材テストスイートの上から順番に複数のテストケースを選択する。選択されるテストケースの個数は、予め決められた定数とする。交叉部123は、選択されたテストケースの遺伝子を配合した新しいテストケースを生成する。例えば、交叉部123は、選択されたテストケースの中から2つのテストケースを無作為に抽出し、2つのテストケースが持つ遺伝子をそれぞれランダムに配合した新しいテストケースを生成する。交叉部123は、この動作を繰り返すことで、予め決められた一定数の新しいテストケースを生成し、新しいテストケースをテストスイートTSに追加する。
ステップS305について、図14を参照して更に説明する。
ステップS401において、交叉部123は、ソートされた素材テストスイートを入力として受け取り、ソートされた素材テストスイートの上から順番に複数のテストケースを抽出する。
ステップS402において、交叉部123は、抽出したテストケース群を入力として受け取り、テストケース群から2つのテストケースを無作為に抽出し、それぞれの遺伝子を無作為に配合した新しいテストケースを生成する。例えば、交叉部123は、テストケース群からテストケースA及びテストケースBを抽出する。ここで、テストケースA及びテストケースBのテストシナリオは同じであるため、テストケースA及びテストケースBは同じidを持つ遺伝子をそれぞれ所有している。交叉部123は、id毎に遺伝子をテストケースA及びテストケースBから無作為に抽出することで新しいテストケースを作成する。例えば、テストケースAの遺伝子が[[id=1,value=0],[id=2,value=1]]であり、テストケースBの遺伝子が[[id=1,value=10],[id=2,value=5]]であるとすると、[[id=1,value=0],[id=2,value=1]],[[id=1,value=0],[id=2,value=5]],[[id=1,value=10],[id=2,value=1]],[[id=1,value=10],[id=2,value=5]]の4通りのテストケースが生成され得る。
ステップS403において、交叉部123は、作成したテストケースとテストスイートTSを入力として受け取り、作成したテストケースをテストスイートTSに追加する。
ステップS404において、交叉部123は、予め決められた一定数の新しいテストケースを作成したか否かを判断し、作成していない場合、ステップS402に戻り、上記の処理を繰り返す。一定数の新しいテストケースを作成した場合、図13のステップS306に戻る。
次に、図13のステップS306において、SBST部115の突然変異部125は、ソートされた素材テストスイートとテストスイートTSとを入力として受け取り、ソートされた素材テストスイートの上から順番に複数のテストケースを選択する。選択されるテストケースの個数は、予め決められた定数とする。突然変異部125は、選択されたテストケースの遺伝子を突然変異した新しいテストケースを生成する。例えば、突然変異部125は、選択されたテストケースが持つそれぞれの遺伝子に対し、一定の確率で新しい値を与えた新しいテストケースを生成する。突然変異部125は、突然変異によって複数の新しいテストケースを生成し、新しいテストケースをテストスイートTSに追加する。
ステップS306について、図15を参照して更に説明する。
ステップS601において、突然変異部125は、ソートされた素材テストスイートを入力として受け取り、ソートされた素材テストスイートの上から順番に複数のテストケースを抽出する。
ステップS602において、突然変異部125は、抽出したテストケースを入力として受け取り、テストケースの各テストデータの各遺伝子に対して、遺伝子のvalueの値を一定確率でランダムな値に変更する。例えば、突然変異部125は、遺伝子のvalue="aaa"を一定確率でvalue="hoge"に変更する。変更する値はどのような値でもよい。また、残りの確率で遺伝子の変更を行わない。確率は予め決められた定数とする。
ステップS603において、突然変異部125は、遺伝子操作されたテストケースとテストスイートTSを入力として受け取り、遺伝子操作されたテストケースをテストスイートTSに追加する。遺伝子操作されたテストケースがテストスイートTSに追加された場合、図13のステップS307に戻る。
次に、テストスイートTSの各テストケースに対し、以下のように出力テストスイートを生成する。
図13のステップS307において、SBST部115は、テストスイートTS内のテストケースを入力として受け取り、テスト対象のプログラムにテストスイートTS内のテストケースを実行させる。コード挿入部111が分岐結果を出力するコードを挿入しているため、テストケースに対し、対応する分岐結果が取得できる。
ステップS309において、SBST部115は、テストスイートTS内のテストケースと、対応する分岐結果と、素材テストスイートを入力として受け取り、テストケースと、対応する分岐結果を素材テストスイートに追加する。
ステップS310において、SBST部115は、テストスイートTS内のテストケースと、対応する分岐結果と、出力テストスイートを入力として受け取り、SBST部115がテストケースを実行して得られた分岐結果と経路一致する分岐結果が出力テストスイートに存在するか否かを判断する。存在しない場合、ステップS311に移行し、存在する場合、ステップS307に戻り、次のテストケースに対する処理を実施し、全てのテストケースに対する処理が終了した場合、ステップS313に移行する。
ステップS311において、SBST部115は、テストスイートTS内のテストケースと、対応する分岐結果と、出力テストスイートを入力として受け取り、テストケースと、対応する分岐結果を出力テストスイートに追加する。
ステップS312において、SBST部115は、SBST部115がテストケースを実行して得られた分岐結果が目標分岐結果と経路一致しているか否かを判断する。経路一致していない場合、ステップS313に移行し、経路一致している場合、図12のステップS206に戻る。
ステップS313においてg=g+1として、ステップS314においてgが最大世代数GになるまでステップS302に戻り、上記の処理を繰り返す。gが最大世代数になった場合、図12のステップS206に戻る。
次に、図12のステップS206においてn=n-1として、ステップS207においてnが0になるまでステップS202に戻り、上記の処理を繰り返す。nが0になった場合、ステップS201に戻り、次の分岐結果に対する処理を実施し、全ての分岐結果に対する処理が終了した場合、図6のステップS009に戻る。
次に、図6のステップS009において、テストデータ生成部105は、出力テストスイートの中の全てのテストケースをファイル等に出力する。
以上の手順により、テストケース生成装置100は、テストシナリオ及びテストデータの組み合わせであるテストケースを出力することができる。
<本発明の実施例の効果>
本発明の実施例によれば、あるテストシナリオが与えられたときに、ソースコード上の分岐を網羅的に通過するテストデータの集合を効率的に生成することが可能になる。
特に、Concolic Testing及びSBSTの性質の異なる2つの手法を組み合わせることで、よりカバレッジの高いテストデータが生成できる。ただし、2つの手法を順番に実行すると、テストデータの生成にかなりの時間を要するため、Concolic Testingを実行している間にSBSTで必要な情報を予め取得することで、SBSTにおけるテストデータの効率的な探索を可能としている。その結果、プログラムの構造的欠陥によるバグの検出能力が向上する。
また、テストシナリオをViewの遷移図から生成することにより、Webアプリケーションにおける画面遷移に対する網羅性の高いテストケースが自動生成できる。WebアプリケーションにおけるViewは画面に非常に近い粒度を持つため、Viewの遷移図に対して状態遷移図に対する所定のカバレッジ基準を用いてテストシナリオを抽出することで、画面遷移の粒度に近く、また、画面遷移に対する網羅性の高いテストシナリオを自動生成できる。
更に、Concolic TestingやSBSTによってテストデータを生成するときに、フレームワークやライブラリ等のユーザが記述していない箇所に対して分岐を解析しないことで、計算爆発を回避することができ、従って、結合テストレベルのテストケースも生成できる。フレームワークやライブラリ等のユーザが記述していない箇所に対してカバレッジを向上させるようなテストケースを生成せず、その代わりに、解析対象のユーザ記述クラスに対するカバレッジの高いテストケース生成に計算リソースを割り当てることができる。
説明の便宜上、本発明の実施例に係るテストケース生成装置は機能的なブロック図を用いて説明しているが、本発明の実施例に係るテストケース生成装置は、ハードウェア、ソフトウェア又はそれらの組み合わせで実現されてもよい。例えば、本発明の実施例は、コンピュータに対して本発明の実施例に係るテストケース生成装置の各機能を実現させるプログラム、コンピュータに対して本発明の実施例に係るテストケース生成方法の各手順を実行させるプログラム等により、実現されてもよい。また、各機能部が必要に応じて組み合わせて使用されてもよい。また、本発明の実施例に係るテストケース生成方法は、実施例に示す順序と異なる順序で実施されてもよい。
以上、あるテストシナリオが与えられたときに、ソースコード上の分岐を網羅的に通過するテストデータの集合を効率的に生成するための手法について説明したが、本発明は、上記の実施例に限定されることなく、特許請求の範囲内において、種々の変更・応用が可能である。