(57)【要約】  【課題】  プログラムをオブジェクトの状態単位で因果関係（依存関係）を分析可能とし、これによりテストにおける入出力の因果関係を分析することで、入力・出力の対応が一意に決定しないシステムに対しても、ブラックボックステストを実行可能とする。  【解決手段】  対象プログラムを１ステップずつ実行し、この１ステップごとに、オブジェクトのフィールドの変更履歴とその変更の原因となったオブジェクトのフィールドの情報を取得して、各オブジェクトの状態単位での因果関係を抽出する因果関係抽出部１０と、所定のオブジェクトを検証対象とし、因果関係抽出部１０により抽出されたオブジェクト間の因果関係に基づき、検証対象のオブジェクトに対する因果関係を分析して原因に当たるオブジェクトを検出し、検出対象のオブジェクトと原因であるオブジェクトとの間に設定されるテストのアサーションに基づいて、テストを実行するテスト実行部２０とを備える。  【選択図】  図１
2006185211.tif 000002
【特許請求の範囲】
【請求項１】
オブジェクト指向言語で記述された対象プログラムを解析する装置において、
前記対象プログラムを１ステップずつ実行するステップ実行部と、
前記ステップ実行部による前記対象プログラムの実行結果に基づき、１ステップごとに、オブジェクトのフィールドの変更履歴とその変更の原因となったオブジェクトのフィールドの情報を取得して、各オブジェクトの状態単位での因果関係を抽出する抽象解釈部と
を備えることを特徴とするプログラム解析装置。
【請求項２】
前記ステップ実行部の機能は、前記対象プログラムのデバッグ用のＡＰＩ（Application Program Interface）を実行することにより実現されることを特徴とする請求項１に記載のプログラム解析装置。
【請求項３】
前記抽象解釈部は、所定のオブジェクトの状態による条件分岐が他のオブジェクトの状態に影響を与えている部分を分析し、当該条件分岐に支配されたオブジェクトの因果関係を取得することを特徴とする請求項１に記載のプログラム解析装置。
【請求項４】
前記抽象解釈部は、前記オブジェクト間の因果関係に基づき、各オブジェクトの各フィールドをノードとし、変更の原因となったフィールドから変更されたフィールドへ向かうエッジを形成した有向グラフを生成することを特徴とする請求項１に記載のプログラム解析装置。
【請求項５】
前記抽象解釈部は、前記フィールドの変更履歴が取得された前記オブジェクトおよびその変更の原因となった前記オブジェクトの少なくとも一部に対してコピーを作成し、所定の記憶装置に保存することを特徴とする請求項１に記載のプログラム解析装置。
【請求項６】
前記抽象解釈部により抽出された前記オブジェクト間の因果関係に基づき、オブジェクトが生存している間のフィールドの変更履歴を生存線として表現し、当該オブジェクトに対してフィールドの変更原因となった他のオブジェクトから矢印を結んで因果関係を記述することにより、同一オブジェクトに対する因果関係をまとめたグラフを生成し出力するグラフ出力部をさらに備えることを特徴とする請求項１に記載のプログラム解析装置。
【請求項７】
対象プログラムのテストを行うテスト実行装置において、
前記対象プログラムを１ステップずつ実行し、この１ステップごとに、オブジェクトのフィールドの変更履歴とその変更の原因となったオブジェクトのフィールドの情報を取得して、各オブジェクトの状態単位での因果関係を抽出する因果関係抽出部と、
所定のオブジェクトを検証対象とし、前記因果関係抽出部により抽出されたオブジェクト間の因果関係に基づき、検証対象の当該オブジェクトに対する因果関係を分析して原因に当たるオブジェクトを検出し、当該検証対象のオブジェクトと原因であるオブジェクトとの間に設定されるテストのアサーションに基づいて、テストを実行するテスト実行部と
を備えることを特徴とするテスト実行装置。
【請求項８】
前記テスト実行部は、テストにおける個々の入力と、その個々の入力から実際に作成されたオブジェクトとの対応をテスト実行前に記録しておき、出力オブジェクトの原因となった入力オブジェクトと当該出力オブジェクトとの関係にアサーションを設定して、テストを行うことを特徴とする請求項７に記載のテスト実行装置。
【請求項９】
前記因果関係抽出部は、前記対象プログラムの実行およびオブジェクト間の因果関係の抽出を２度行い、１度目は抽出されたオブジェクト間の因果関係を記憶装置に保存し、２度目は当該オブジェクト間の因果関係に加えて前記テスト実行部によりテストの対象とされたオブジェクトのコピーを作成し、記憶装置に保存することを特徴とする請求項７に記載のテスト実行装置。
【請求項１０】
前記因果関係抽出部により抽出された前記オブジェクト間の因果関係に基づき、オブジェクトが生存している間のフィールドの変更履歴を生存線として表現し、当該オブジェクトに対してフィールドの変更原因となった他のオブジェクトから矢印を結んで因果関係を記述することにより、同一オブジェクトに対する因果関係をまとめたグラフを生成し出力するグラフ出力部をさらに備えることを特徴とする請求項７に記載のテスト実行装置。
【請求項１１】
コンピュータが対象プログラムの解析を行う方法であって、
前記コンピュータが、前記対象プログラムを１ステップずつ実行し、実行結果を取得し、記憶装置に格納する第１のステップと、
前記コンピュータが、取得された前記実行結果を前記記憶装置から読み出し、当該実行結果に基づき、１ステップごとに、オブジェクトのフィールドの変更履歴とその変更の原因となったオブジェクトのフィールドの情報を取得し、オブジェクト間の因果関係を抽出して、記憶装置に格納する第２のステップと、
前記コンピュータが、前記オブジェクト間の因果関係を前記記憶装置から読み出し、これらの情報に基づき、各オブジェクトの各フィールドをノードとし、変更の原因となったフィールドから変更されたフィールドへ向かうエッジを形成した有向グラフを生成する第３のステップと
を含むことを特徴とするプログラム解析方法。
【請求項１２】
前記コンピュータが、所定のオブジェクトの状態による条件分岐が他のオブジェクトの状態に影響を与えている部分を分析し、当該条件分岐に支配されたオブジェクトの因果関係を取得するステップをさらに含み、
前記第３のステップでは、前記条件分岐に基づく因果関係を含めて前記有向グラフを生成することを特徴とする請求項１１に記載のプログラム解析方法。
【請求項１３】
前記コンピュータが、所定のオブジェクトを検証対象とし、前記第２のステップで抽出された前記オブジェクト間の因果関係に基づき、検証対象の当該オブジェクトに対する因果関係を分析して原因に当たるオブジェクトを検出するステップと、
前記コンピュータが、当該検証対象のオブジェクトと原因であるオブジェクトとの間に設定されるテストのアサーションに基づいて、テストを実行するステップと
をさらに含むことを特徴とする請求項１１に記載のプログラム解析方法。
【請求項１４】
前記コンピュータが、第２のステップで抽出された前記オブジェクト間の因果関係に基づき、オブジェクトが生存している間のフィールドの変更履歴を生存線として表現し、当該オブジェクトに対してフィールドの変更原因となった他のオブジェクトから矢印を結んで因果関係を記述することにより、同一オブジェクトに対する因果関係をまとめたグラフを生成し出力するステップをさらに含むことを特徴とする請求項１１に記載のプログラム解析方法。
【請求項１５】
前記同一オブジェクトに対する因果関係をまとめたグラフを出力するステップでは、所定のオブジェクトを基点として、当該オブジェクトに影響を与えた他のオブジェクトおよびフィールドを漸進的に表示することを特徴とする請求項１４に記載のプログラム。
【請求項１６】
前記コンピュータが、所定のオブジェクトを検証対象とし、前記第２のステップで抽出された前記オブジェクト間の因果関係に基づき、検証対象の当該オブジェクトに対する因果関係を分析して原因に当たるオブジェクトを検出するステップと、
前記コンピュータが、当該検証対象のオブジェクトと原因であるオブジェクトとの間に設定されるテストのアサーションに基づいて、テストを実行するステップと、
前記テストにおいて、失敗したことまたは成功したことを条件として、当該テストの対象であったオブジェクトに関して、前記第３のステップで生成された有向グラフに基づいて、同一オブジェクトに対する因果関係をまとめたグラフを生成し出力するステップと
をさらに含むことを特徴とする請求項１１に記載のプログラム解析方法。
【請求項１７】
コンピュータに、
検索対象のプログラムを１ステップずつ実行し、実行結果を取得し、記憶装置に格納する第１の処理と、
取得された前記実行結果を前記記憶装置から読み出し、当該実行結果に基づき、１ステップごとに、オブジェクトのフィールドの変更履歴とその変更の原因となったオブジェクトのフィールドの情報を取得し、オブジェクト間の因果関係を抽出して、記憶装置に格納する第２の処理と、
前記オブジェクト間の因果関係を前記記憶装置から読み出し、これらの情報に基づき、各オブジェクトの各フィールドをノードとし、変更の原因となったフィールドから変更されたフィールドへ向かうエッジを形成した有向グラフを生成する第３の処理と
を実行させることを特徴とするプログラム。
【請求項１８】
前記コンピュータに、所定のオブジェクトの状態による条件分岐が他のオブジェクトの状態に影響を与えている部分を分析し、当該条件分岐に支配されたオブジェクトの因果関係を取得する処理をさらに実行させ、
前記第３の処理では、前記条件分岐に基づく因果関係を含めて前記有向グラフを生成する処理を前記コンピュータに実行させることを特徴とする請求項１７に記載のプログラム。
【請求項１９】
前記コンピュータに、
所定のオブジェクトを検証対象とし、前記第２の処理で抽出された前記オブジェクト間の因果関係に基づき、検証対象の当該オブジェクトに対する因果関係を分析して原因に当たるオブジェクトを検出する処理と、
当該検証対象のオブジェクトと原因であるオブジェクトとの間に設定されるテストのアサーションに基づいて、テストを実行する処理と
をさらに実行させることを特徴とする請求項１７に記載のプログラム。
【請求項２０】
前記コンピュータに、第２の処理で抽出された前記オブジェクト間の因果関係に基づき、オブジェクトが生存している間のフィールドの変更履歴を生存線として表現し、当該オブジェクトに対してフィールドの変更原因となった他のオブジェクトから矢印を結んで因果関係を記述することにより、同一オブジェクトに対する因果関係をまとめたグラフを生成し出力する処理をさらに実行させることを特徴とする請求項１７に記載のプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、プログラム解析に関し、特にオブジェクト指向言語で記述されたプログラムに対して動的解析により依存関係を抽出する技術に関する。
【背景技術】
【０００２】
コンピュータシステムにおいて、システムの仕様から知ることができる入力と出力の関係が本質的に非決定的である場合、入力と出力の因果関係も確定しているわけではない場合が多い。例えば、マルチスレッドシステムでは、入力が複数やってきたときの処理の順番が非決定的にスレッドの実行状態により変動し、出力が入力から一意的に決定できないことがある。これは、スレッドを多用して並列実行度を向上させたプログラミングモデルでは、非常に一般的な状況である。
【０００３】
上記のようなシステムに対してテストを行う場合、出力に対応する入力を特定できないため、入力と出力の間のアサーションを記述することができない。ここで、テストとは、一般的にはモデルと実装との整合性を検証する行為である。ブラックボックステストは、仕様のみをモデル側の知識としてテストを行う手法であり、テスト対象システム（ＳＵＴ：System Under Test）に対して、入力を与え、出力を得、入出力が仕様に適合しているかを検証する行為である。テストの一つ一つはテストケースと呼ばれ、値の入力と出力の組から構成される。
【０００４】
アサーションでは、入力と出力の拘束条件が記述される。例えば、与えられた実数（ｄ）のｎ乗根を超えない最大の整数（Ｍ）を計算するシステムを考える。これを、一つの実数と一つの整数（ｎ）を入力とし、一つの実数を出力とするシステムとすると、以下のような条件式がアサーションとなる。
((M^n < =d) && (((M+1)^n) > d))
【０００５】
さて、システムの仕様通りの動作が確定的に記述できない場合にテストを実施する、従来技術を用いた手法としては、メッセージ履歴をトレースして検証する手法や、データによる因果関係を実行時にトレースする手法を応用することが考えられる。
メッセージ履歴をトレースして検証する手法を応用する場合、オブジェクト間のメソッド呼び出し等のメッセージ履歴から、出力に対する入力を特定することが考えられる。従来、オブジェクト指向のプログラムの実行時解析における実行時トレースを利用し、並列実行時の因果関係を分析する手法や動作の因果関係を分析する手法（例えば、非特許文献１参照）、実行時のある時点においてオブジェクトの関係や変更を問い合わせできる手法（例えば、非特許文献２参照）等が提案されている。
【０００６】
また、データによる因果関係を実行時にトレースする手法を応用する場合、物理的なメモリデータに対するアクセス履歴から、出力に対する入力を特定することが考えられる。従来、データの因果関係を実行時にトレースすることによってグラフとして抽出して因果関係を分離し効率よく差分デバッグするオブジェクトの情報を考慮せずに、データの因果関係を抽出して誤りを探す手法（例えば、非特許文献３参照）、トレースしたデータの依存関係の分析結果を分かりやすくグラフ表示する手法（例えば、非特許文献４参照）等が提案されている。
【０００７】
【非特許文献１】Shreeram Sahasrabudhe and Hector Munoz-Avila. “Mining Cause-Effect Sequential Patterns from Action Traces”, ［online］, August 2003, ［２００４年１２月１日検索］, インターネット＜ＵＲＬ：http://www.lehigh.edu/~sas4/html/ShreeramMunoz-ICML2003.PDF＞
【非特許文献２】Raimondas Lencevicius, Urs Holzle and Ambuj K. Singh. “Dynamic Query-Based Debugging of Object-Oriented Programs”, Journal of Automated Software Engineering, Volume 10, Number 1, pp. 39-74, Kluwer, January 2003.
【非特許文献３】Andreas Zeller. “Isolating Cause-Effect Chains from Computer Programs”, Proc. of ACM SIGSOFT 10th International Symposium on the Foundations of Software Engineering (FSE-10), pp. 1-10, November 2002.
【非特許文献４】Thomas Zimmermann and Andreas Zeller. “Visualizing Memory Graphs”, Proc. of the Dagstuhl Seminar 01211 "Software Visualization", Lecture Notes in Computer Science (LNCS) 2269, pp. 191-204, Springer-Verlag, May 2001.
【発明の開示】
【発明が解決しようとする課題】
【０００８】
上述したように、メッセージ履歴をトレースして検証する手法や、データによる因果関係を実行時にトレースする手法を応用することにより、システムの仕様通りの動作が確定的に記述できない場合にテストの実施を可能とする方法が考えられる。しかし、これらのテスト方法はいずれも、仕様のみをモデル側の知識として行うブラックボックステストには適用することができない。
【０００９】
メッセージ履歴をトレースして検証する手法を行うには、内部メッセージによって実際にシステムにどのような結果を生み出したのかを予め知っておく必要がある。すなわち、内部メッセージの仕様を知っている必要がある。このような情報は、ブラックボックステストを前提としている場合には得ることができない。さらに、現実のシステムにおいては、メッセージ履歴だけがオブジェクトの相互作用に関わっているとは限らず、例外や、直接のフィールド操作によってオブジェクトの変更が行われることがある。そのため、メッセージ履歴のトレースのみで、テストにおける十分な入出力の因果関係を得ることはできない。
【００１０】
また、非特許文献２に開示される従来技術は、オブジェクトの関係や変更に対する問い合わせができる対話式のデバッガのようなものであり、ある時間で切ってみれば、因果関係分析に必要な情報を得ることは理論的には可能と考えられる。しかし、この手法でシステム全体の履歴を取るには、変更の単位で実行を中断し、問い合わせを実行し、ログを取ることになるため、現実的とは言えない。
【００１１】
データによる因果関係を実行時にトレースする手法では、この手法をＪａｖａ（米国サン・マイクロシステムズ社の商標）のようなＧＣ（ガーベージ・コレクション）を提供するオブジェクト指向言語に適用する場合は、移動の単位であるオブジェクトと物理的なメモリデータの関係を外部から与える必要がある。ＧＣを提供するオブジェクト指向言語では、値を保持するアドレスが実行時に変化するためである。また、テストにおいてアサーションを検証することができたとしても、テスト実行後の解析において、あるアサーションが失敗した場合になぜそのアサーションが失敗したかを知ることは、デバッグにおいて非常に重要な情報である。しかし、データによる因果関係分析では、オブジェクト情報が欠落しているため、得られた因果関係から失敗の原因を知ることは困難である。
【００１２】
非特許文献３、４に開示される従来技術においても、オブジェクトを構成するメタデータに対する考慮を因果関係に入れていないため、データの依存関係がどのオブジェクトに対応しているのかという情報が欠落していることになる。したがって、ＳＵＴに対して、メモリの特定のアドレスに書いた内容が入力であると指定するような非現実的な仕様を与えない限り、オブジェクト指向環境におけるテストの入力との因果関係とは直接に結びつけることはできない。
【００１３】
また、データによる因果関係分析を用いて、フィールド間の因果関係を分析するためには、データがどのようにオブジェクトを構成しているかのメタデータを必要とする。すなわち、どのデータが、どのオブジェクトのフィールドに対応するかの情報が必要になる。従来技術を単純に適用して、データを基本として因果関係を分析した場合には、上記のようなメタデータを与えない限り、その因果関係の分析時にはオブジェクトの情報を得ることができない。この場合は、対話的デバッグ時にオブジェクトを意識した操作が困難になることが予想される。
【００１４】
なお、テストやデバッグのための手法ではないが、実行時に、このような因果関係分析を利用するものとして、汚染フラグが挙げられる。これは、Ｐｅｒｌなどで利用されている手法で、動的に変数に「汚染された」という状態が記憶され、そのフラグが情報の伝達とともに伝播するようになっている。したがって、その変数の中が危険な情報を含む可能性があるかどうかを調べて、セキュリティチェックに利用することができる。しかし、この手法は「汚染された」という高々ひとつの情報の因果関係分析にしか利用できず、一般的な手法とは言えない。
【００１５】
本発明は、以上のような技術的課題に鑑みてなされた。その目的は、オブジェクト指向言語で記述されたプログラムに対して、オブジェクトの状態単位で因果関係（依存関係）を分析可能とすることにある。そして、これにより、オブジェクト指向言語で記述されたシステムのテストにおいて、入出力の因果関係をオブジェクトの状態単位で分析可能とし、システムの仕様からは入力・出力の対応が一意に決定しないようなシステムに対しても、ブラックボックステストを実行可能とすることにある。
【課題を解決するための手段】
【００１６】
上記の目的を達成するため、本発明は、対象プログラムのテストを行う、次のように構成された装置として実現される。この装置は、対象プログラムを１ステップずつ実行し、この１ステップごとに、オブジェクトのフィールドの変更履歴とその変更の原因となったオブジェクトのフィールドの情報を取得して、各オブジェクトの状態単位での因果関係を抽出する因果関係抽出部と、所定のオブジェクトを検証対象とし、因果関係抽出部により抽出されたオブジェクト間の因果関係に基づき、検証対象のオブジェクトに対する因果関係を分析して原因に当たるオブジェクトを検出し、検証対象のオブジェクトと原因であるオブジェクトとの間に設定されるテストのアサーションに基づいて、テストを実行するテスト実行部とを備えることを特徴とする。
【００１７】
より詳細には、この因果関係抽出部は、対象プログラムを１ステップずつ実行するステップ実行部と、このステップ実行部による前記対象プログラムの実行結果に基づき、１ステップごとに、オブジェクトのフィールドの変更履歴とその変更の原因となったオブジェクトのフィールドの情報を取得して、各オブジェクトの状態単位での因果関係を抽出する抽象解釈部とを備える。そして、この抽象解釈部は、所定のオブジェクトの状態による条件分岐が他のオブジェクトの状態に影響を与えている部分を分析し、当該条件分岐に支配されたオブジェクトの因果関係を取得する。さらに、この抽象解釈部は、オブジェクト間の因果関係に基づき、各オブジェクトの各フィールドをノードとし、変更の原因となったフィールドから変更されたフィールドへ向かうエッジを形成した有向グラフを生成する。
【００１８】
また、テスト実行部は、テストにおける個々の入力と、その個々の入力から実際に作成されたオブジェクトとの対応をテスト実行前に記録しておき、出力オブジェクトの原因となった入力オブジェクトと当該出力オブジェクトとの関係にアサーションを設定して、テストを行うことができる。一方、因果関係抽出部は、対象プログラムの実行およびオブジェクト間の因果関係の抽出を２度行い、１度目は抽出されたオブジェクト間の因果関係を記憶装置に保存し、２度目は当該オブジェクト間の因果関係に加えてテスト実行部によりテストの対象とされたオブジェクトのコピーを作成することができる。
【００１９】
また、この装置は、因果関係抽出部により抽出されたオブジェクト間の因果関係に基づき、オブジェクトが生存している間のフィールドの変更履歴を生存線として表現し、このオブジェクトに対してフィールドの変更原因となった他のオブジェクトから矢印を結んで因果関係を記述することにより、同一オブジェクトに対する因果関係をまとめたグラフを生成し出力するグラフ出力部をさらに備える。
【００２０】
また、上記の目的を達成する本発明は、コンピュータが対象プログラムの解析を行う、次のような方法としても実現される。この方法は、コンピュータが、対象プログラムを１ステップずつ実行する第１のステップと、この実行結果に基づき、１ステップごとに、オブジェクトのフィールドの変更履歴とその変更の原因となったオブジェクトのフィールドの情報を取得し、オブジェクト間の因果関係を抽出する第２のステップと、このオブジェクト間の因果関係に基づき、各オブジェクトの各フィールドをノードとし、変更の原因となったフィールドから変更されたフィールドへ向かうエッジを形成した有向グラフを生成する第３のステップとを含むことを特徴とする。また、この方法は、所定のオブジェクトを検証対象とし、第２のステップで抽出されたオブジェクト間の因果関係に基づき、検証対象のオブジェクトに対する因果関係を分析して原因に当たるオブジェクトを検出するステップと、検証対象のオブジェクトと原因であるオブジェクトとの間に設定されるテストのアサーションに基づいて、テストを実行するステップとをさらに含む構成とすることができる。さらにこの方法は、第２のステップで抽出されたオブジェクト間の因果関係に基づき、オブジェクトが生存している間のフィールドの変更履歴を生存線として表現し、オブジェクトに対してフィールドの変更原因となった他のオブジェクトから矢印を結んで因果関係を記述することにより、同一オブジェクトに対する因果関係をまとめたグラフを生成し出力するステップをさらに含む構成とすることができる。ここで、同一オブジェクトに対する因果関係をまとめたグラフを出力するステップでは、所定のオブジェクトを基点として、当該オブジェクトに影響を与えた他のオブジェクトおよびフィールドを漸進的に表示する。またこの方法では、上述したテストを行った場合に、そのテストが失敗したことまたは成功したことを条件として、グラフを表示することができる。
【００２１】
さらに本発明は、コンピュータを制御して上述した装置として機能させるプログラム、あるいはコンピュータに上記のプログラム解析方法における各ステップに対応する処理を実行させるプログラムとしても実現される。このプログラムは、磁気ディスクや光ディスク、半導体メモリ、その他の記録媒体に格納して配布したり、ネットワークを介して配信したりすることにより提供することができる。
【発明の効果】
【００２２】
以上のように構成された本発明によれば、解析対象のプログラムを１ステップずつ実行しながら情報を収集して、各オブジェクトのフィールドの変更履歴およびその変更の原因である情報を取得することにより、オブジェクトの状態単位の因果関係を取得する。この因果関係を参酌することにより、オブジェクト指向言語で記述されたプログラムのテストにおいて、入出力の因果関係をオブジェクトの状態単位で分析することが可能となる。そして、仕様から入出力の対応が一意に決定しないシステムに対しても、入出力の対応関係を把握できるので、ブラックボックステストを行うことが可能となる。
【発明を実施するための最良の形態】
【００２３】
本発明は、まず、プログラムの実行時にシステムの動作をトレースすることによって、オブジェクトの変更の因果関係を分析する。具体的には、あるオブジェクトの状態が、どのオブジェクトの状態によって作成・変更されたかを因果関係として有向グラフ（この有向グラフを、以下、依存グラフと呼ぶ）にする。そして、依存グラフを分析して出力結果に用いられた入力を求め、入力出力間の条件を検証することにより、対象システム（プログラム）のテストを実行する。これにより、テスト対象であるシステム（プログラム）に手を加えることなく、ブラックボックステストが実現可能となる。また、表示用に編集された依存グラフを表示することにより、ユーザは、注目しているオブジェクト（例えば不正なオブジェクト）やアサーションに現れるオブジェクトの状態がどのオブジェクトの状態から作られたのかを効率よく分析し、デバッグを行うことができる。
以下、添付図面を参照して、本発明を実施するための最良の形態（以下、実施形態）について詳細に説明する。
【００２４】
図１は、本実施形態によるテスト実行装置の機能構成を示す図である。
図１に示すテスト実行装置１００は、テスト対象であるプログラム（以下、対象プログラム）におけるオブジェクトの状態単位の因果関係を抽出する因果関係抽出部１０と、因果関係抽出部１０により抽出された因果関係を用いてテストを実行するテスト実行部２０と、因果関係抽出部１０により抽出された因果関係を表示出力するグラフ出力部３０とを備える。このテスト実行装置１００は、パーソナルコンピュータやワークステーション、その他のコンピュータシステムにて実現される。
【００２５】
図２は、図１のテスト実行装置１００を実現するのに好適なコンピュータのハードウェア構成の例を模式的に示した図である。
図２に示すコンピュータは、演算手段であるＣＰＵ（Central Processing Unit：中央処理装置）１０１と、Ｍ／Ｂ（マザーボード）チップセット１０２およびＣＰＵバスを介してＣＰＵ１０１に接続されたメインメモリ１０３と、同じくＭ／Ｂチップセット１０２およびＡＧＰ（Accelerated Graphics Port）を介してＣＰＵ１０１に接続されたビデオカード１０４と、ＰＣＩ（Peripheral Component Interconnect）バスを介してＭ／Ｂチップセット１０２に接続された磁気ディスク装置（ＨＤＤ）１０５、ネットワークインタフェース１０６と、さらにこのＰＣＩバスからブリッジ回路１０７およびＩＳＡ（Industry Standard Architecture）バスなどの低速なバスを介してＭ／Ｂチップセット１０２に接続されたフレキシブルディスクドライブ１０８およびキーボードやマウス等の入力デバイス１０９とを備える。
【００２６】
なお、図２は本実施形態を実現するコンピュータのハードウェア構成を例示するに過ぎず、本実施形態を適用可能であれば、他の種々の構成を取ることができる。例えば、ビデオカード１０４を設ける代わりに、ビデオメモリのみを搭載し、ＣＰＵ１０１にてイメージデータを処理する構成としても良いし、外部記憶装置として、ＡＴＡ（AT Attachment）やＳＣＳＩ（Small Computer System Interface）などのインタフェースを介してＣＤ−Ｒ（Compact Disc Recordable）やＤＶＤ−ＲＡＭ（Digital Versatile Disc Random Access Memory）のドライブを設けても良い。
【００２７】
図１に示すテスト実行装置１００の因果関係抽出部１０は、例えば、図２のプログラム制御されたＣＰＵ１０１とメインメモリ１０３や磁気ディスク装置１０５等の記憶装置により実現される。この因果関係抽出部１０は、対象プログラムにおいて、あるオブジェクトの状態（フィールド）が、どのオブジェクトの状態によって変更・作成されたのかに着目して因果関係を記述する（なお、配列もオブジェクトと考える。配列の各々の要素および配列の長さをフィールドとみなす）。すなわち、トレースにより得られるデータの依存関係に加えて、オブジェクト状態の単位での依存関係を解析し、因果関係の記述手段として依存グラフを作成する。
【００２８】
因果関係抽出部１０は、図１に示すように、ステップ実行部１１と、抽象解釈部１２とを備える。ステップ実行部１１は、対象プログラムを１ステップずつ実行し、イベントを取得して、例えば図２に示したＣＰＵ１０１のキャッシュメモリ等の記憶装置に保持する。ステップ実行部１１の機能は、既存のデバッガのためのＡＰＩ（Application Program Interface：以下、このデバッガのためのＡＰＩをデバッグＡＰＩと呼ぶ）により提供することができる。抽象解釈部１２は、データ依存関係のトレースを行う。ステップ実行部１１により取得され記憶装置に保持されているイベントを抽象解釈部１２が読み出して解釈することで、データの依存関係の最小単位である命令に注目してオブジェクトの因果関係を得ることができる。このような構成を取ることにより、テストケースとテスト対象システムの実装の間における独立性が保存される。
【００２９】
ここで、因果関係について、さらに説明する。
オブジェクトの状態が条件分岐によって因果関係を結ぶ場合がある。図３にそのようなコードの例を示す。
このコードにおいて、o1.fieldによる分岐から影響を受けた状態の変更は、全てo1.fieldと因果関係を有するものと考える。つまり、o2はo1により影響を受けていると考える。このように、制御依存から生み出される因果関係の原因を、「弱原因（weak-causality）」と呼ぶ。分岐命令を含むメソッドに対して制御フロー解析（静的解析）を行うことによって、このような弱原因を因果関係に取り入れることができる。なお、制御依存関係はデータ依存関係に等価に置き換えることができるため、弱原因をわざわざ特別扱いする意味はないようにも見える。しかし、Ｊａｖａのような手続き型言語では、制御依存関係とデータ依存関係は、通常は違った目的に用いられる。また、一般に、これらの言語では、制御フローの変化から与える影響の範囲は、非常に広範囲にわたり、その結果、弱原因をそのまま表示すると、多くの場合、非常に多くの関係が表示されてしまう。したがって、弱原因を通常の原因と分離することはプログラムの解析においては有用である。
【００３０】
次に、因果関係抽出部１０による依存グラフの作成方法について詳細に説明する。
まず、スロットという概念を定義する。スロットとは、ローカル変数、スタックスロット（これら二つはスレッドコンテキスト依存）、オブジェクトのフィールド（クラスフィールドおよびインスタンスフィールド）による領域一般（格納場所）を示す概念である。このスロットを用いることにより、次のように依存関係を定義することができる。
（スロット１，・・・，スロットｎ）→スロット
上記の定義において、左辺は依存元を表しており、右辺は依存先を表している。すなわち上式は、ｎ個の依存元と１個の依存先から構成されている。これは、左辺で示されたｎ個のスロットから右辺で示されたスロットの値がセットされたことを意味している。なお、オブジェクトの識別は、デバッグＡＰＩが提供する各オブジェクトのユニークなＩＤを用いたり、抽象解釈部１２がオブジェクトの生成を補足して自らユニークなＩＤを付与したりすることによって行うことができる。
【００３１】
因果関係抽出部１０において、上述したステップ実行部１１が対象プログラムを１ステップずつ実行し、抽象解釈部１２はステップ実行部１１からイベントを取得することにより、対象プログラムのどの命令が実行されたかの情報を得る。そして、抽象解釈部１２は、この情報に基づき、あるスタックのスロットの値が何によって作られたのかを一つ一つ追っていく。また、ローカル変数のアクセスに対しても同じように因果関係を追っていく。最終的にオブジェクトのフィールドにセットされた時点で、オブジェクトのフィールド間の因果関係が結ばれることになる。
【００３２】
抽象解釈部１２は、このようにしてオブジェクトにおけるフィールド間の因果関係の情報を取得していき、スロットの変更履歴のリスト（依存リスト）を作成し、例えば図２に示したメインメモリ１０３やＣＰＵ１０１のキャッシュメモリに保持する。この依存リストは、上記の依存関係を、実際にそのような代入が起きた順序を保つようにして、リスト化したものである。また依存リストには、対象プログラムにおけるソースコードの各リスト項目に対応する命令列が、オブジェクトにおけるフィールド間の因果関係に対応付けられて登録される。
【００３３】
図４は、このようにして作成された依存リストの例を示す図である。また、図５は、図４の依存リストにおける命令列と実際にスロットの変更が行われる際のスタックの状態との対応を示す図である。なお、図４に示す例では命令列としてＪａｖａのバイトコードが示されている。また、図５では、スタックにオブジェクトがロードされる命令（ALOAD LO(03)、ALOAD LO(01)、ALOAD LO(02)）は記載されていない。
図４、５を参照することにより、この命令列を実行した場合には、ある特定のオブジェクトのフィールドＡ、Ｂを原因として、フィールドＣを結果とする因果関係を得ることができる。なお、上述した弱原因に関しては、その影響の及ぶ範囲が非常に広範囲にわたることから、通常の原因と分離することが有用であった。そこで、図４のような依存リストに登録する場合や後述の依存グラフを生成する場合、弱原因であることが識別できるような付加データを付して、通常の原因と区別する（後述するように、依存グラフを表示用に編集して出力する場合には、因果関係の表現方法を変えて視覚的に識別できるようにすることができる）。
【００３４】
そして抽象解釈部１２は、図４の依存リストからさらに、各スロットの依存関係を表すグラフ（依存グラフ）を生成する。
図６は、図４の依存リストから生成される依存グラフを示す図である。また、図７は、依存リストから依存グラフを生成する手順を説明するフローチャートである。
図７を参照すると、抽象解釈部１２は、まず図４に示したような依存リストと共に、スロットからグラフのノードへの辞書（ハッシュテーブル等）を用意する（ステップ７０１）。そして、依存リストから未処理の依存関係を一つ取り出し、依存先に対応する新しいノードを作る。この新規ノードには依存リストにおけるこの依存関係の番号が格納される（ステップ７０２、７０３）。
【００３５】
次に、抽象解釈部１２は、辞書から依存元のスロットに対応するノードを取り出す。辞書にノードが見つからなかった依存元に対しては、その依存元に対して新しいノードを作成する。この新規ノードに対しても依存リストの番号が格納される（ステップ７０４）。
【００３６】
次に、抽象解釈部１２は、依存元のノードから依存先のノードへ向かうエッジを張り、グラフを結ぶ（ステップ７０５）。そして、辞書に、依存先のスロットに対応するノードを登録する（ステップ７０６）。
【００３７】
この後、抽象解釈部１２は、ステップ７０２に戻り、依存リストに未処理の依存関係が残っているか調べ、残っていれば、その依存関係の一つを取り出し、ステップ７０３からステップ７０６までの動作を繰り返す。依存リストに登録されている全ての依存関係に対して処理が行われたならば、次に抽象解釈部１２は、これまでの動作で作成された依存グラフに対して、スタックもしくはローカル変数を表現したノードを消去する。そして、そのノードに元々つながっていた依存関係をエッジで直接つなぎ、処理を終了する（ステップ７０７）。
【００３８】
なお、上記のようにスロットの変更履歴を保存する方法のほかに、オブジェクトもしくはフィールドの単位でコピーを作成して保存するという手法でも依存グラフの生成に要する情報を得ることが可能である。このようにスロットの変更履歴やオブジェクト（あるいはフィールド）のコピーを保存しておくことによって、全ての時点でのオブジェクトの状態を再現することができるようになる。場合によっては、全ての時点でのオブジェクトの状態が必ずしも必要というわけではなく、デバッグ解析時もしくはテスト実行時のオブジェクトの状態を知るだけでも十分な場合も多い。例えば、不変的（immutable）なオブジェクトでは、状態の変更が起きないので、最終状態だけを知るだけで十分である。しかし、通常であれば、参照されなくなったオブジェクトはＧＣ（ガーベージ・コレクション）によって消去されてしまうので、後述のテストやデバッグを行う場合に、最終状態のオブジェクトすら得ることができない場合がある。このような、実行中に一時的にしか存在しないオブジェクトに対し、適当な配列に記録したり、デバッグＡＰＩの機能（例えば、ＪａｖａのデバッグＡＰＩであるＪＤＩ（Java Debugger Interface）の場合であれば、ObjectReference.disableCollection() API）を用いてＧＣから対象オブジェクトを保護することで、いつでもオブジェクトの状態を得ることができるようになる。さらに、スロットの変更履歴を記録する際、その変更に関連したオブジェクトのコピーを保存することにより、デバッグ時に、より詳細なオブジェクトの状態を得ることが可能となる。また、変更履歴の記録、コピーを行わなかった場合でも、実行中に一時的にしか存在しないオブジェクトに対し、上述のようにＧＣから対象オブジェクトを保護することで、テストやデバッグに利用することが可能となる。
【００３９】
また、このような一時オブジェクトの状態の記録や、スロットの変更履歴を、全て保存しようとする場合、大量のメモリ容量を要するため、実用に耐えない場合があり得る。これを解決する方策として、オブジェクトの状態における因果関係の抽出（対象プログラムのトレース）を２度にわたって行うことが考えられる。この場合、１度目のトレースでは、オブジェクトのＩＤと因果関係の記録だけを残しておき、一時オブジェクトの状態の記録や、スロットの変更履歴の保存は行わない。そして、１度目のトレースによって得られた因果関係の記録を用いて、注目するオブジェクトに対する逆問題を解く（選択オブジェクトの状態に影響を与えているオブジェクトの因果関係グラフにおいて、選択オブジェクトを出発点にして上流探索する）。例えば、注目するオブジェクトとは、テストの場合は出力であり、デバッグの場合はデバッグの対象となるオブジェクトである。２度目のトレースでは、探索で出現したオブジェクトに対してのみ、一時オブジェクトの状態の記録やスロットの変更履歴の保存を行う。なお、２度目のトレースでは、１度目のトレースと同一の実行パターンである必要があるため、必要に応じて、ｄｅＪａＶｕや、ＣｏｎＴｅｓｔなどの、再実行が可能な実行環境を用いると良い。
【００４０】
ここで、Ｊａｖａ言語で記述された対象プログラムを解析する場合であって、ステップ実行部の機能を提供するデバッグＡＰＩにＪＤＩを用いた場合を例として、この実装例におけるデータ依存関係のトレース方法を説明する。
Ｊａｖａ言語を含む、例外処理機構を持つ手続き型オブジェクト指向言語では、以下の命令からデータ依存関係をトレースする。
１．    フレーム内データ依存
１．１．スタック変数の定義参照（スタックマシンの場合のみ）  （段落［００４６］参照）
１．２．ローカル変数の定義参照          （段落［００４６］参照）
２．    フレーム間データ依存
２．１．メソッド呼び出し時の実引数      （段落［００４７］参照）
２．２．メソッドから戻り時の戻り値      （段落［００４８］参照）
２．３．例外の発生と捕捉                （段落［００４９］参照）
３．    スレッド（オブジェクト）間データ依存
３．１．フィールド変数の定義参照        （段落［００５０］参照）
【００４１】
Ｊａｖａ仮想機械（Virtual Machine：ＶＭ）の命令セットは、Java Virtual Machine Specification （Ｊａｖａ仮想機械仕様）で定義されている。Ｊａｖａ仮想機械仕様は各命令につき、演算の意味、オペランドスタックの増減、副作用などを定義しているが、フィールドとメソッド呼び出し時の引数及び戻り値の型に関してあいまい性がある。そして、それらの実際の型は、メソッドを実装するクラスのConstantPoolの対応するエントリを参照しないと決まらない。Ｊａｖａ仮想機械は、１スロット＝３２ビットのアーキテクチャであり、６４ビットのlongとdouble型のオペランドは連続する２スロットを使用する。そのため、スタック変数の定義参照時にオペランドの型が不明であるとスタックレベルの調整が正しくできない。
【００４２】
本実装例では、デバッグＡＰＩにＪａｖａ Debugger Interface （ＪＤＩ）を用いる。ＪＤＩは、デバッガなどがＪａｖａ仮想機械で実行されるプログラムの実行を制御したり、内部状態にアクセスしたりするために用いるＪａｖａ  ＡＰＩであり、ステップ実行やブレークポイントなどのデバッガ実装のための基本的な機能を提供している。本実装例では、このＪＤＩを用いてテスト対象システムをステップ実行し、得られた命令列を、データ依存関係のみに注目してトレースする。スタック変数のデータ依存関係のトレースには、スタックレベルの調整のためにオペランドの大きさを知る必要がある。しかし、ＪＤＩはクラスのConstantPoolにアクセスする手段を提供していない。そこで、簡単のためにオペランドの型にあいまい性があるフィールドの定義参照とメソッド呼び出しと戻りに関して、ステップイベントに加えて、より多くの情報を提供する専用イベントを併用することが考えられる。ただし、実際にはＪａｖａの型システムはメソッド内の到達可能な任意の位置でスタック変数の型の一意性を保証しているので、ほとんどの場合、メソッドの静的解析によりスタック変数の型のあいまい性を除くことができる。
【００４３】
抽象解釈部１２によるイベントのトレースは、システム全体および上述したデータ依存関係をトレースする命令（フレーム内データ依存、フレーム間データ依存、スレッド（オブジェクト）間データ依存）のそれぞれについて、以下のように行う。
システム全体
抽象解釈部１２は、テスト対象システムの開始時には、テスト対象システムの全クラス（フィルター設定可能）に対するClassPrepareEvent要求をセットする。そして、テスト対象システムの全スレッド（フィルター設定可能）全クラス（フィルター設定可能）に対するExceptionEvent要求、MethodEntryEvent要求、MethodExitEvent要求をセットする。また、テスト対象システムの全スレッド（フィルター設定可能）に対するThreadStartEvent要求をセットする。
【００４４】
また、抽象解釈部１２は、クラスのロード時には、ClassPrepareEventの処理時にそのクラスの全フィールド（フィルター設定可能）に対してModificationWatchpointEvent要求、AccessWatchpointEvent要求をセットする。
さらに、抽象解釈部１２は、スレッドの開始時には、ThreadStartEventの処理時に、抽象解釈機械にも対応するスレッドを作成する。さらにそのスレッドが実行する全クラス（フィルター設定可能）のメソッドのStepEvent要求をセットする。
【００４５】
フレーム内データ依存
抽象解釈部１２は、スタック変数の定義参照およびローカル変数の定義参照のいずれにおいても、命令が参照する複数の変数のデータ依存の和集合を、その命令が定義する変数のデータ依存として、対応するスロットに記録する。
【００４６】
フレーム間データ依存
抽象解釈部１２は、メソッド呼び出し時の実引数に関して、MethodEntryEventの処理時に、抽象解釈機械の対応するスレッドに新しいフレームを作成する。そして、メソッドの実引数に相当するローカル変数のデータ依存を一つ前のフレームのスタックトップからコピーする。
【００４７】
また、抽象解釈部１２は、メソッドから戻り時の戻り値に関して、MethodExitEventの処理時に、スタックトップのデータ依存を戻り値のデータ依存として現在のフレームに記録する。そして、同じスレッドの次の命令のStepEventの処理時に、まずフレームを一つポップし、戻ったメソッドの実引数分をスタックからポップし、戻ったメソッドの戻り値のデータ依存をスタックトップのデータ依存としてプッシュする。
【００４８】
さらに、抽象解釈部１２は、例外の発生と捕捉に関して、スタックトップのデータ依存を例外オブジェクトのデータ依存として現在のフレームに記録する。そして、同じスレッドの次の命令のStepEventの処理時に、まず例外発生フレームと現在のフレームの差分だけフレームをポップし、スタックを全てポップし、例外オブジェクトのデータ依存をスタックトップのデータ依存としてプッシュする。
【００４９】
スレッド（オブジェクト）間データ依存
抽象解釈部１２は、フィールド変数の定義参照に関して、ModificationWatchpointEventの処理時に、スタックトップのデータ依存をポップし、当該オブジェクトの当該フィールド変数のデータ依存としてセットする。そして、AccessWatchpointEventの処理時に、当該オブジェクトの当該フィールド変数のデータ依存をスタックトップのデータ依存としてプッシュする。
【００５０】
以上の実装例は、対象プログラムがＪａｖａ言語で記述されたプログラムである場合の実装の一例過ぎない。実際には、本実施形態が実現されるシステムの動作環境や使用言語（Ｊａｖａ言語あるいはＪａｖａ言語以外のオブジェクト指向言語）等に応じて種々の実装形態を取ることができる。
【００５１】
以上のようにして、オブジェクトの状態単位での因果関係が反映された依存グラフが生成される。生成された依存グラフは、例えば図２のメインメモリ１０３等の記憶装置に格納され、テスト実行部２０およびグラフ出力部３０により利用される。実行時にオブジェクトの情報を取得するための他の実装法としては、テスト対象システムにイベントを発生させるコードを追加する方法や、テスト対象システムが仮想機械上で実行されるものについては、仮想機械を変更し仮想機械の命令実行と同時にデータ依存をトレースする方法が考えられる。しかし、上述した本実施形態によれば、
１）テスト対象システムを変更しないことでその挙動を変えない、
２）汎用のデバッグＡＰＩを用いることでテスト対象システムが仮想機械で実行されるものに制限されない、
３）仮想機械を変更しないことで特定の仮想機械の実装に依存しない、
などの利点がある。
【００５２】
なお、テスト及びデバッグには出力の計算に関与しないオブジェクト間のデータ依存関係は必ずしも必要でない。そこで、それらに対する命令をステップ実行の対象から外すことで、ステップ実行部１１により不要なイベントが作成され、抽象解釈部１２が受け取ってそれを無視するコスト自体を除くことができる。また、テスト対象システム内に存在するが、テスト対象システムの実行に影響がないことが予めわかっているスレッドも、ステップ実行対象から外すことができる。例えば、Ｊａｖａ仮想機械で実行されるプログラムの場合、finalizerやreference handlerなどのシステムスレッドやデバッグＡＰＩ自身のスレッドなどがそのようなスレッドに相当する。
【００５３】
本実施形態では、対象プログラムのテストにおける入出力の因果関係を解析したり、デバッグ時に失敗の原因を追及したりするために、上記のようにして得られた依存グラフを用いることができる。
テスト実行部２０は、例えば、図２のプログラム制御されたＣＰＵ１０１とメインメモリ１０３により実現される。このテスト実行部２０は、対象プログラムのブラックボックステストを実行する。すなわち、対象プログラムによるシステムに対して、入力を与え、出力を得、入出力が仕様に適合しているかをアサーションで調べる。この際の、入出力間の因果関係の分析に、因果関係抽出部１０により生成された依存グラフを用いることができる。すなわち、依存グラフに基づいて検証したいオブジェクトに対する因果関係を分析して、その原因となったオブジェクトとを特定する。そして、この検証したいオブジェクトとその原因となったオブジェクトとの間にアサーションを設定してテストを行うことができる。
【００５４】
テストの実行時、入力オブジェクトは変更を受けたり消去されたりするおそれがある。これに対して、上述した一時オブジェクトをトレースする手法を用いて対処することも可能であるが、テストの実行のためだけであるならば、より効率的な方法を取ることができる。すなわち、予めテストの実行前に、テストの入力とその入力によって生成されたオブジェクトとの対応関係を取っておけば良い。アサーションを検証する際には、依存グラフを用いた因果関係分析によって、出力オブジェクトに対応する入力オブジェクト（これは、生存していないかもしれないし、変更されているかもしれない）を取得する。そして、その入力オブジェクトからテストの入力を取得することによって、入力と出力のアサーションを検証することが可能になる。
【００５５】
グラフ出力部３０は、例えば、図２のプログラム制御されたＣＰＵ１０１とメインメモリ１０３およびビデオカード１０４により実現される。このグラフ出力部３０は、因果関係抽出部１０によって生成された依存グラフを編集し、オブジェクト間の因果関係表示用のグラフ（以下、表示用グラフ）を生成してディスプレイ装置に表示出力する。表示用グラフは、具体的には、オブジェクトが生存している間のスロットの変更履歴を生存線として表現し、このオブジェクトに対してスロットの変更原因となった他のオブジェクトから表す矢印を結んで因果関係を記述する（フィールドの情報は、矢印の近傍に記述する）。これによって、同一オブジェクトに対する因果関係をまとめて表示することができ、ユーザが参照して因果関係を解析することが容易となる。生存線の開始点は、他のオブジェクトとの因果関係が初めて観測された点、終了点は、最後に観測された地点とすれば良い。また、ユーザが指定した、あるいはテストの検証対象となったオブジェクトを起点として、そのオブジェクトに影響を与えたオブジェクトやフィールドを漸進的に表示することで、因果関係の解析を、より容易にすることが可能となる。
【００５６】
図８乃至図１１は、表示用グラフの例を示す図である。同図の例では、ＵＭＬシーケンス図に似た形式で図示している。
図８乃至図１１の例では、テスト実行部２０のテストにより得られた出力値（Output）が正しいかどうかが検証される。まず、Ｏｕｔｐｕｔオブジェクトを起点として因果関係をたどると、ＡｖｅｒａｇｅオブジェクトがＯｕｔｐｕｔオブジェクトにａｖｅｒａｇｅを出力したという関係がわかる（図８参照）。次に、Ａｖｅｒａｇｅオブジェクトから因果関係をたどると、Ａｖｅｒａｇｅオブジェクトと２つのＲｅｓｕｌｔオブジェクトとの関係がわかる。Ａｖｅｒａｇｅオブジェクトは、２つのＲｅｓｕｌｔオブジェクトからｐｒｉｃｅフィールドを得ている（図９参照）。
【００５７】
さらに、Ｒｅｓｕｌｔオブジェクトから因果関係をたどると、２つのＲｅｓｕｌｔオブジェクトは、それぞれＲｅｓｕｌｔＳｅｔからコピーされたということがわかる（図１０参照）。そして、Ａｖｅｒａｇｅオブジェクトに対する弱原因を展開して表示させると、Ｒｅｓｕｌｔオブジェクトのｔｉｍｅフィールドと、Ｒｅｑｕｅｓｔオブジェクトのｓｔａｒｔ、ｅｎｄフィールドを比較する条件分岐から、そのＲｅｓｕｌｔオブジェクトを平均の計算に用いるべきかどうかのチェックをしていることによる因果関係が表示される（図１１参照）。弱原因は、一般的に広い範囲に影響を与えるので、点線で表示するなど、他の因果関係と区別して視認性を高める表示方法を工夫することが好ましい。
【００５８】
図１２は、図１１の表示用グラフと対象プログラムのソースコードとを並べて表示した状態を示す図である。
図１２のソースコードの記載において、表示色が反転している行は、表示用グラフにおいてポインタ（矢印）１２０１が指し示す線（因果関係）に対応するコードである。すなわち、表示用グラフにおいて所望の因果関係を選択すると、実際にどのコードによって、その因果関係が結ばれたかが示される。因果関係抽出部１０が依存グラフを生成するために依存リストを生成した時点で、依存関係（スロットの変更）とこれに対応するコード（命令）が分かっているので、グラフ出力部３０が依存グラフからこの情報を読み取ることで、図１２のような対応表示が可能となる。
【００５９】
なお、対象プログラムにループがある場合、表示用グラフが複雑になるのを防ぐため、ループ部分については、最初は、ループであることを示すマーク等を付してコンパクトに表示しておく。そして、このループ部分に対してマウスクリック等のアクションが行われた時点で、ループ部分を展開して表示するといった表示制御を行うこともできる。
【００６０】
図１３は、グラフ出力部３０による表示用グラフの生成手順を説明するフローチャートである。
図１３を参照すると、グラフ出力部３０は、まず、因果関係抽出部１０により生成されメインメモリ１０３等の記憶装置に格納されている依存グラフを読み出して用意する（ステップ１３０１）。また、オブジェクトＩＤと配列を対応付ける辞書（ハッシュテーブル等）を用意する（ステップ１３０２）。
【００６１】
次に、グラフ出力部３０は、依存グラフから、解析したいオブジェクトのオブジェクトＩＤに対応する未処理のノードを一つ取り出す（ステップ１３０３）。未処理のノードがあるならば、そのオブジェクトＩＤで辞書を引いて配列を取り出し、取り出した配列に対してステップ１３０３で取り出されたノードを追加する（ステップ１３０４、１３０５）。そして、配列に追加されたノードを処理済みとマークする（ステップ１３０６）。
【００６２】
ステップ１３０３からステップ１３０６までの動作を繰り返し、解析したいオブジェクトのオブジェクトＩＤに対応する未処理のノードがなくなったならば（ステップ１３０４でＮｏ）、次にグラフ出力部３０は、辞書に格納されている全ての配列について、各々の配列に格納されているノードを依存リストの番号でソートする（ステップ１３０７）。
【００６３】
以上のようにして、同一オブジェクトに対する因果関係がまとめられた表示用グラフが生成される。グラフ出力部３０は、ビデオカード１０４により、この表示用グラフの画像データを生成し、ディスプレイ装置に表示する。なお、グラフ出力部３０は、テスト実行部２０によるテストにおいて失敗、あるいは成功したことを条件に、この表示用グラフの生成および表示出力を行うようにすることができる。
【図面の簡単な説明】
【００６４】
【図１】本実施形態によるテスト実行装置の機能構成を示す図である。
【図２】図１のテスト実行装置を実現するのに好適なコンピュータのハードウェア構成の例を模式的に示した図である。
【図３】本実施形態の解析対象であるプログラムにおいて、オブジェクトの状態が条件分岐によって因果関係を結ぶようなコードの例を示す図である。
【図４】本実施形態により作成される依存リストの例を示す図である。
【図５】図４の依存リストにおける命令列と実際にスロットの変更が行われる際のスタックの状態との対応を示す図である。
【図６】図４の依存リストから生成される依存グラフの例を示す図である。
【図７】本実施形態における依存リストから依存グラフを生成する手順を説明するフローチャートである。
【図８】本実施形態におけるオブジェクト間の因果関係表示用のグラフの生成例を説明する図であり、OutputオブジェクトとAverageオブジェクトの因果関係を示す図である。
【図９】本実施形態におけるオブジェクト間の因果関係表示用のグラフの生成例を説明する図であり、AverageオブジェクトからResultオブジェクトへの因果関係を示す図である。
【図１０】本実施形態におけるオブジェクト間の因果関係表示用のグラフの生成例を説明する図であり、ResultオブジェクトとResultSetオブジェクトとの関係を示す図である。
【図１１】本実施形態におけるオブジェクト間の因果関係表示用のグラフの生成例を説明する図であり、Averageオブジェクトに対する弱原因であるRequestオブジェクトからの因果関係を示す図である。
【図１２】図１１の表示用グラフと対象プログラムのソースコードとを並べて表示した状態を示す図である。
【図１３】本実施形態のグラフ出力部による表示用グラフの生成手順を説明するフローチャートである。
【符号の説明】
【００６５】
１０…因果関係抽出部、１１…ステップ実行部、１２…抽象解釈部、２０…テスト実行部、３０…グラフ出力部、１００…テスト実行装置、１０１…ＣＰＵ（Central Processing Unit：中央処理装置）、１０３…メインメモリ、１０４…ビデオカード、１０５…磁気ディスク装置（ＨＤＤ）
【図１】
2006185211.tif 000003
【図２】
2006185211.tif 000004
【図３】
2006185211.tif 000005
【図４】
2006185211.tif 000006
【図５】
2006185211.tif 000007
【図６】
2006185211.tif 000008
【図７】
2006185211.tif 000009
【図８】
2006185211.tif 000010
【図９】
2006185211.tif 000011
【図１０】
2006185211.tif 000012
【図１１】
2006185211.tif 000013
【図１２】
2006185211.tif 000014
【図１３】
2006185211.tif 000015