【文献】
岡本 隆史,ユカイ、ツーカイ、カイハツ環境!(16)単体テストを“神速”化するQuick JUnitとMockito [online],2010年08月02日,[検索日 2021.07.14], Internet: <URL: https://www.atmarkit.co.jp/ait/articles/1008/02/news095.html>
【文献】
牛山 克彦, ほか,DBプログラミング教室−JavaによるDBアクセスのイロハを学ぶ 第11回,Java WORLD,日本,(株)IDGジャパン,2005年,第9巻 第10号
【文献】
伊藤 清人,総復習!現代Java開発の必修技術 J2SE 5.0新言語機能、Eclipse、DI×AOPコンテナ、O/Rマッピング・フレームワーク、ユニット・テスティング・フレームワーク−主要技術の要点を一挙に押さえる Part 5,Java WORLD ,日本,(株)IDGジャパン,2007年,第11巻 第1号
【文献】
北嵐 直樹, ほか,徹底論考! ソフトウェア・テスト 各論2,Java WORLD,日本,(株)IDGジャパン,2004年,第8巻 第9号
(58)【調査した分野】(Int.Cl.,DB名)
【発明を実施するための形態】
【0012】
以下、実施形態について図面を参照しつつ説明する。以下の説明において、同一又は類似する部分に共通の符号を付して重複する説明を省略することがある。
【0013】
まず本実施形態の前提となる技術として、プログラム(ビジネスロジック)のテストに用いるテストデータを記号実行(「シンボリック実行」とも称される。)を利用して情報処理装置(コンピュータ)により自動生成する技術について説明する。記号実行は、プログラムのソースコードに記述されている変数値を具体化せずに記号(シンボル値)の状態で実行する技術である。
【0014】
テストデータの自動生成に際し、まず情報処理装置は、テスト対象のプログラムを記号実行することによりプログラムが実行し得るパス(以下、「実行パス」と称する。)を抽出し、抽出した実行パスを通るための条件式(以下、「パス条件」と称する。)を求める。そして情報処理装置は、求めたパス条件を充足する(制約充足可能な)具体的な変数値を求め、求めた変数値をテストデータとする。尚、上記具体的な変数値は、例えば、SMTソルバ(Satisfiability Modulo Theories Solver)により求めることができる。
【0015】
記号実行について、テスト対象のプログラムが
図1に示すソースコード50である場合を例として説明する。まず情報処理装置は、ソースコード50を解析(字句分析、構文分
析等)することにより同図に示す実行木60を生成する。実行木60は、パス条件(上欄)と変数状態(下欄)との組み合わせで表される複数のノードN1〜N5を含む。
【0016】
実行木60の生成に際し、情報処理装置は、まずソースコード50に記述されている変数に記号(「記号変数」とも称される。)を割り当てる。本例の場合、情報処理装置は、ソースコードの1行目に記述されている入力変数「x」に記号「α」を割り当てている。
【0017】
続いて情報処理装置は、根ノード(ルートノード)であるノードN1を生成する。本例では、情報処理装置は、ノードN1のパス条件(上欄)に任意の変数状態に対して条件が成立する(「真」となる)ことを意味する「条件無し」を設定し、変数状態(下欄)に入力変数「x」に記号「α」を割り当てていることを示す「x=α」を設定する。
【0018】
続いて情報処理装置は、ソースコードの2行目のif文(条件分岐文)について、上記if文が真(true)の場合に対応するノードN2と、上記if文が偽(false)の場合に
対応するノードN3とを生成する。そして情報処理装置は、ノードN2のパス条件(上欄)に「α>0」を設定し、変数状態(下欄)に「x=α」を設定する。また情報処理装置は、ノードN3のパス条件(上欄)に「!(α>0)」を設定し、変数状態(下欄)に「x=α」を設定する。
【0019】
続いて情報処理装置は、ソースコードの3行目のif文(条件分岐文)について、上記if文が真(true)である場合に対応するノードN4と、上記if文が偽(false)であ
る場合に対応するノードN5を生成する。そして情報処理装置は、ノードN4のパス条件(上欄)にノードN3のパス条件(上欄)「!(α>0)」と上記if文が真(true)の場合のパス条件「(α<0)」との論理積である「!(α>0)&&(α<0)」を設定し、変数状態(下欄)に「x=α」を設定する。また情報処理装置は、ノードN5のパス条件(上欄)にノードN3のパス条件(上欄)「!(α>0)」と上記if文が偽(false)の場合のパス条件「!(α<0)」との論理積である「!(α>0)&&!(α<0
)」を設定し、変数状態(下欄)に「x=α」を設定する。
【0020】
ここでノードN2〜N5の夫々は、テスト対象のプログラムの実行パスに対応している。情報処理装置は、各実行パスのパス条件を充足する(制約充足可能な)変数の具体値をSMTソルバにより求め、求めた実行パス(テストケース)毎の具体値を、各実行パスを検証するためのテストデータとする。本例では、ノードN2のパス条件(実行パス)について変数値xの具体値「10」を、ノードN4のパス条件(実行パス)について変数値xの具体値「−20」を、ノードN5のパス条件(実行パス)について変数値xの具体値「0」を、夫々テストデータとして求めている。
【0021】
ところで、
図2(a)に示すように、テスト対象のプログラム21のソースコードがDAO22(DAO:Data Access Object)を介してデータベース23にアクセスする記述を
含んでいるが、DAO部分の開発を他社が行っていたり、データベースとは独立して単体テストを行いたいといった理由により、DAO22が未実装の環境でプログラム21のテストを行わなければならないことがある。またソースコードの記号実行による解析時にデータベースへのアクセスを抑制したいことがある。
【0022】
そのような場合、例えば、
図2(b)に示すように、DAO22の機能を代用させるスタブ24(stub)を用意することが有効であるが、DAOが未実装の環境であるため、プログラム21のソースコードを記号実行してもスタブの出力値(データベースにアクセスした際の返値。以下、「スタブ出力値」と称する。)を得ることができない。そこで本実施形態のスタブ生成支援装置10は、記号実行を利用してスタブ出力値を取得し、取得したスタブ出力値を利用してスタブを自動生成する。これによればDAOが未実装の環境で
もスタブを自動生成することができる。以下、スタブ生成支援装置10の構成並びに機能について詳述する。
【0023】
図3にスタブ生成支援装置10のハードウェア構成を示している。同図に示すように、スタブ生成支援装置10は、プロセッサ11、主記憶装置12、補助記憶装置13、入力装置14、出力装置15、及び通信装置16を備える。これらは図示しないバス等の通信手段を介して互いに通信可能に接続されている。尚、同図に示すハードウェアはスタブ生成支援装置10として利用できる装置の一例に過ぎず、例えば、スタブ生成支援装置10の機能を通信可能に接続された複数の情報処理装置を用いて実現してもよい。またスタブ生成支援装置10を、例えば、クラウドシステムにより提供されるクラウドサーバのような仮想的な情報処理資源を用いて実現してもよい。
【0024】
プロセッサ11は、例えばCPU(Central Processing Unit)やMPU(Micro Processing Unit)を用いて構成されている。プロセッサ11が、主記憶装置12に格納されているプログラム(補助記憶装置13から読み出されて主記憶装置12に格納されるプログラムを含む。)を読み出して実行することにより、スタブ生成支援装置10の様々な機能が実現される。
【0025】
主記憶装置12は、プログラムやデータを記憶する装置であり、例えば、ROM(Read
Only Memory)、RAM(Random Access Memory)、不揮発性メモリ(NVRAM(Non Volatile RAM))等である。
【0026】
補助記憶装置13は、例えば、ハードディスクドライブ、SSD(Solid State Drive
)、光学式記憶装置(CD(Compact Disc)、DVD(Digital Versatile Disc)等)、各種ストレージシステム、ICカード、SDメモリカードや光学式記録媒体等の記録媒体の読取/書込装置、クラウドサーバの記憶領域等である。補助記憶装置13に格納されているプログラムやデータは主記憶装置12に随時読み込まれる。
【0027】
入力装置14は、例えば、キーボード、マウス、タッチパネル、カードリーダ、音声入力装置等である。出力装置15は、ユーザに処理経過や処理結果等の各種情報を提供するユーザインタフェースであり、例えば、画像表示装置(液晶モニタ、LCD(Liquid Crystal Display)、グラフィックカード等)、音声出力装置(スピーカ等)、印字装置等である。スタブ生成支援装置10が実行するプログラムや当該プログラムが利用するデータは、例えば、記録媒体に記録されて提供され、入力装置14(カードリーダ等)を介して補助記憶装置13に取り込まれる。尚、例えば、スタブ生成支援装置10が通信装置16を介して他の装置との間で情報の入力や出力を行う構成としてもよい。
【0028】
通信装置16は、LAN(Local Area Network)やインターネット等の通信手段を介した他の装置との間の通信を実現する有線方式又は無線方式の通信インタフェースであり、例えば、NIC(Network Interface Card)、無線通信モジュール、USB(Universal Serial Interface)モジュール、シリアル通信モジュール等である。スタブ生成支援装置10が実行するプログラムや当該プログラムが利用するデータは、例えば、通信装置16を介して補助記憶装置13に取り込まれる。
【0029】
図4にスタブ生成支援装置10が備える主な機能を示している。同図に示すように、スタブ生成支援装置10は、解析用ソースコード生成部111、DTOソースコード解析部112、記号実行部113、スタブ出力値生成部114、スタブ生成部115、ソースコード記
憶部150、スタブ化対象記憶部160、DTO情報記憶部170、記号実行結果記憶部180、及びスタブ情報記憶部190を備える。
【0030】
尚、スタブ生成支援装置10は、上記の機能の他、例えば、オペレーティングシステム、ファイルシステム、デバイスドライバ、DBMS(DataBase Management System)等の機能を備えていてもよい。スタブ生成支援装置10は、各種の情報(データ)を、例えば、データベースのテーブルやファイルとして記憶する。
【0031】
同図に示すように、ソースコード記
憶部150は、テスト対象ソースコード151、DTOソースコード152、及び解析用ソースコード153を記憶する。テスト対象ソースコード151は、テスト対象となるプログラムのソースコードである。DTOソースコード152は、DAOの関数の戻り値を受け取るDTOのソースコードである。解析用ソースコード153は、テスト対象ソースコード151に基づき生成されるソースコードである。
【0032】
スタブ化対象記憶部160は、スタブ化対象情報161を記憶する。スタブ化対象情報161は、テスト対象ソースコード151に含まれている記述から、スタブ化の対象となる命令(記述)を特定する情報を含む。
【0033】
DTO情報記憶部170は、DTO情報171を記憶する。DTO情報171は、DTOソースコード152に基づき生成された情報を含む。
【0034】
記号実行結果記憶部180は、記号実行結果181を記憶する。記号実行結果181は、記号実行部113が解析用ソースコード153について記号実行を行うことにより得られる情報(以下、記号実行結果と称する。)を含む。
【0035】
スタブ情報記憶部190は、スタブ出力値191とスタブ192を含む。
【0036】
図5は、スタブ生成支援装置10が備える機能とスタブ生成支援装置10が記憶するデータの関係を説明するデータフロー図である。同図に示すように、解析用ソースコード生成部111は、テスト対象ソースコード151、スタブ化対象情報161、及びDTO情報171に基づき、解析用ソースコード153を生成する。DTOソースコード解析部112は、DTOソースコード152を解析することによりDTO情報171を生成する。記号実行部113は、解析用ソースコード153を記号実行することにより記号実行結果181を生成する。スタブ出力値生成部114は、記号実行結果181とDTO情報171に基づきスタブ出力値191を生成する。スタブ生成部115は、スタブ出力値191に基づきスタブ192を生成する。
【0037】
図6は、スタブ生成支援装置10が行う処理(以下、スタブ生成処理S600と称する。)を説明するフローチャートである。以下、同図とともにスタブ生成処理S600について説明する。尚、S615〜S617の処理の説明に際し、
図11を適宜参照する。
【0038】
同図に示すように、まず解析用ソースコード生成部111が、ソースコード記憶部150からテスト対象ソースコード151を、スタブ化対象記憶部160からスタブ化対象情報161を、夫々読み込む(S611)。
【0039】
尚、以下の説明では、一例として、解析用ソースコード生成部111が、
図7に示す、所定のオブジェクト指向言語で記述されたテスト対象ソースコード151と、
図8に示す構成のスタブ化対象情報161を読み込むものとする。
【0040】
図7に示すように、テスト対象ソースコード151は、選択的に実行される処理A及び処理Bの記述を含む。
図8に示すように、スタブ化対象情報161は、レコード番号1521、DAO名1522、関数名1523、及び戻り値型名1524の各項目を有する一
つ以上のレコードで構成されている。
【0041】
図6に戻り、続いて解析用ソースコード生成部111は、読み込んだテスト対象ソースコード151に記述されている命令を順次取得し(S612)、読み込んだ命令毎にS613〜S617の処理を実行する。
【0042】
まずS613では、解析用ソースコード生成部111は、取得中の命令がスタブ化対象情報161でスタブ化の対象とされている関数であるか否かを判定する。
図7に示すテスト対象ソースコード151の場合、
図8のスタブ化対象情報161に記述されている、関数名1523が「selectById」という関数の呼び出しを含んでいる。そのため、解析用ソースコード生成部111は、現在取得中の命令が、
図7のソースコードの「FooDto fooDto = fooDao.selectById(x);」である場合、判定結果を「YES」とする(S613:Y
ES)。その後、処理はS614に進む。一方、現在取得中の命令が
図7のソースコードの「FooDto fooDto = fooDao.selectById(x);」でない場合、解析用ソースコード生成部
111は、判定結果を「NO」とする(S613:NO)。その後、処理はS618に進む。
【0043】
S614では、DTOソースコード解析部112が、スタブ化対象情報161から、取得中の命令が呼び出している関数の戻り値を受け取るDTOソースコード152を取得してこれを解析することによりフィールドの情報を取得する。そしてDTOソースコード解析部112は、取得したフィールドの情報に基づきDTO情報171を生成する。
【0044】
例えば、現在取得中の命令が
図7のテスト対象ソースコード151の「FooDto fooDto = fooDao.selectById(x);」である場合、DTOソースコード解析部112は、スタブ化
対象情報161から「selectById」という関数名1523に対応づけられているDTO名1522「FooDao」を取得し、取得したDTO名「FooDao」に対応するDTOソースコード152を取得してこれを解析することによりフィールドの情報を取得する。
【0045】
図9にDTOソースコード152の一例を示す。DTOソースコード152が同図に示すものである場合、DTOソースコード解析部112は、当該DTOソースコード152に記述されている「int id」、「int numA」、「int numB」をフィールドの情報として取得し、取得したフィールドの情報に基づきDTO情報171を生成する。
【0046】
図10に
図9のDTOソースコード152に基づき生成されるDTO情報171の一例を示す。同図に示すように、DTO情報
171は、DTOテーブル1711とフィールドテーブル1712を含む。このうちDTOテーブル1711には、DTOソースコード152の識別子であるDTO_ID17111とDTOの名称であるDTO名17112との対応が管理されている。一方、フィールドテーブル1712は、フィールドID17121、DTO_ID17122、フィールド名17123、及び型名17124の各項目を有する一つ以上のレコードを含む。
【0047】
図6に戻り、S615では、解析用ソースコード生成部111が、テスト対象ソースコード151の入力値を定義している記述に、S614で取得したフィールドの情報に対応する変数の記述を追記する。例えば、上記のようにフィールドの情報として「int id」、「int numA」、「int numB」を取得している場合、
図11に示すように、解析用ソースコード生成部111は、
図7のソースコードにおける「int funcA(int x) 」の記述中に「int id, int numA, int numB)」という記述を追記して「int funcA(int x, int id, int numA, int numB)」とする。
【0048】
S616では、解析用ソースコード生成部111が、テスト対象ソースコード151に
、DTO型のダミー変数の初期化命令、及びダミー変数へのDTOのフィールドの代入命令を追記する。
【0049】
例えば、
図7のソースコード151の場合、
図11に示すように、解析用ソースコード生成部111は、DTO型のダミー変数の初期化命令として、テスト対象ソースコード151に「FooDto fooDao#selectById = new FooDto();」を追記する。また解析用ソースコード生成部111は、ダミー変数へのDTOのフィールドの代入命令として、テスト対象ソースコード151に「fooDao#selectById.setId(id);」、「fooDao#selectById.setNumA(numA);」、「fooDao#selectById.setNumB(numB);」を追記する。
【0050】
S617では、解析用ソースコード生成部111が、ソースコード151のスタブ化対象の関数の呼び出し命令をダミー変数の代入命令に置換する。
図7のソースコード151の場合、
図11に示すように、解析用ソースコード生成部111は、スタブ化対象関数の呼び出し「FooDto fooDto = fooDao.selectById(x);」をダミー変数の代入命令「FooDto fooDto = fooDao#selectById;」に置換する。
【0051】
図6のS618では、スタブ出力値生成部110は、ソースコード151に記述されている全ての命令をS612で取得済か否か判定する。ソースコード151に記述されている全ての命令を取得済でない場合(S618:NO)、処理はS612に戻る。ソースコード151に記述されている全ての命令を取得済である場合(S618:YES)、処理はS619に進む。
【0052】
S619では、解析用ソースコード生成部111が、S615〜S618の処理を行うことにより生成されたソースコードを解析用ソースコード153として記憶する。本例の場合、解析用ソースコード生成部111は、
図12に示すソースコードを解析用ソースコード153として記憶する。
【0053】
続いて
図6のS620では、記号実行部113が解析用ソースコード153を記号実行することにより記号実行結果181を生成する。
【0054】
図13は、記号実行部113が
図12に示す解析用ソースコード153を記号実行することにより生成される記号実行結果181である。同図に示すように、記号実行結果181は、ケースID1811と各入力変数に対応する項目1812〜1815の各項目とを有する一つ以上のレコードで構成される。記号実行結果181の1つのレコードにおける項目1812〜1815の値は、解析用ソースコード153の1つの実行パス(テストケース)の各入力変数の具体値である。
【0055】
尚、
図13におけるケースID1811が「1」のレコードの具体値は、
図12に示す解析用ソースコード153の後段のif文の処理Aを通る実行パスに対応している。また
図13におけるケースID1811が「2」のレコードは、
図12に示す解析用ソースコード153の後段のif文の処理Bを通る実行パスに対応している。
【0056】
図6のS621では、スタブ出力値生成部110が、記号実行結果181とDTO情報171のフィールドテーブル1712とに基づき、スタブ出力値191を生成する。記号実行結果181が
図13に示す内容である場合、スタブ出力値生成部110は、
図13に示す記号実行結果181から、
図10のフィールドテーブル1712に存在しない入力変数「x」の列を除く項目1813〜1815の値を取得することにより、
図14に示すスタブ出力値191を生成する。
【0057】
尚、スタブ出力値生成部110が、例えば、スタブ出力値191を、
図15に示すよう
に所定の記述形式(同図の例はXML(Extensible Markup Language)形式)で記述されたファイル(以下、スタブ出力値ファイル191Aと称する。)として出力するようにしてもよい。そのようにすることで、スタブ出力値191を効率よく管理することができ、またスタブ出力値191を効率よく利用することができる。上記所定の記述形式は、HTML(HyperText Markup Language)等の他の記述形式でもよい。
【0058】
続いて、
図6のS622では、スタブ生成部115が、スタブ出力値191に基づきスタブ192を生成する。
【0059】
図16に、
図15のスタブ出力値ファイル191Aに基づき2つのスタブ192(スタブ192a,スタブ192b)が生成される様子を示す。スタブ生成支援装置10は、例えば、スタブ192の雛型の記述を記憶しており、スタブ生成部115は、雛型の記述を利用してスタブ192を生成する。生成されたスタブ192は、例えば、ソースコード151のテストや解析に際して用いられる。尚、
図17に示すように、スタブ192aは、ソースコード151のif文の処理Aの実行パスの処理を実行させる。またスタブ192bは、ソースコード151のif文の処理Bの実行パスの処理を実行させる。
【0060】
以上に説明したように、本実施形態のスタブ生成部115によれば、効率よく自動的にスタブ192を生成することができる。そのため、DAOの開発を他社が行っている場合や、データベースとは独立して単体テストを行いたい場合等、DAOが未実装の環境でも、データベース23にアクセスする記述を含むテスト対象ソースコード151を効率よくテストすることができる。また例えば、ソースコードの記号実行による解析時にデータベースへのアクセスを抑制することができる。
【0061】
以上、本発明について実施の形態に基づき具体的に説明したが、本発明は上記の実施の形態に限定されるものではなく、その要旨を逸脱しない範囲で種々変更可能であることはいうまでもない。例えば、上記の実施の形態は本発明を分かりやすく説明するために詳細に説明したものであり、必ずしも説明した全ての構成を備えるものに限定されるものではない。また上記実施形態の構成の一部について、他の構成の追加・削除・置換をすることが可能である。
【0062】
また上記の各構成、機能部、処理部、処理手段等は、それらの一部または全部を、例えば、集積回路で設計する等によりハードウェアで実現してもよい。また上記の各構成、機能等は、プロセッサがそれぞれの機能を実現するプログラムを解釈し、実行することによりソフトウェアで実現してもよい。各機能を実現するプログラム、テーブル、ファイル等の情報は、メモリやハードディスク、SSD(Solid State Drive)等の記録装置、また
はICカード、SDカード、DVD等の記録媒体に置くことができる。
【0063】
また上記の各図において、制御線や情報線は説明上必要と考えられるものを示しており、必ずしも実装上の全ての制御線や情報線を示しているとは限らない。例えば、実際にはほとんど全ての構成が相互に接続されていると考えてもよい。
【0064】
また以上に説明したスタブ生成支援装置10の各種機能部、各種処理部、各種データベースの配置形態は一例に過ぎない。各種機能部、各種処理部、各種データベースの配置形態は、スタブ生成支援装置10が備えるハードウェアやソフトウェアの性能、処理効率、通信効率等の観点から最適な配置形態に変更し得る。
【0065】
また前述した各種データベースの構成(スキーマ(Schema)等)は、リソースの効率的な利用、処理効率向上、アクセス効率向上、検索効率向上等の観点から柔軟に変更し得る。