はじめに

テスト対象システムのすべてのコンポーネントが、定義されたワイヤプロトコルや、トラフィックを別のホストや別のエンドポイントに向けるためにテスト対象アプリケーション (AUT) を簡単に再構成することで仮想化できる API を介して通信するわけではありません。場合によっては、アプリケーション コードを直接変更しないと制御できない API を介して統合が行われます。

Java AUT を使用しているチームの場合、Parasoft の Java 仮想化エージェントを使用して、Java メソッド呼び出しをアプリケーション JVM 内で直接記録し、これらの呼び出しの動作を仮想化することができます。Parasoft Java 仮想化エージェントは、RMI、リモート EJB 呼び出し、または依存システムに機能や接続を提供するその他の内部開発コードを仮想化するのに特に便利です。

要件

方法論

テスト対象アプリケーションは、JVM 起動パラメーターとして設定された Parasoft エージェントを使用して起動されます。そのエージェントの設定は、指定されたターゲット クラスとメソッドのそれぞれについて、非アクティブモード、記録モード、仮想化モードのいずれであるかを示します。

エージェントが記録モードになったら、記録したい動作でテスト対象アプリケーションを実行できます。エージェントは、メソッド呼び出しのデータをローカルファイルに保存します。記録された動作を表す仮想アセットを作成するには、そのファイルを Virtualize の仮想アセット作成ウィザードに渡します。

目的の動作が記録されたら、エージェントを仮想化モードに切り替え、Virtualize 仮想アセットの HTTP エンドポイントを使用して設定できます。これで、同じメソッド呼び出しが実際のメソッドではなく Virtualize PVA にリダイレクトされます。以前に記録されたオブジェクト インスタンスが返されます。

以下は、Oracle WebLogic medrec サンプル アプリケーションで記録されたサンプル PVA です。

Java 仮想化のパターン

Java メソッドの呼び出しを記録し、その戻り値を仮想化するために使用できる 2 つの異なる仮想化パターンがあります。

適用する最適なパターンは、アプリケーションのニーズによって異なります。2 つの仮想化パターンを混在させたり、指定されたクラス/メソッドごとにさまざまなモードを混在させたりすることができます。

クラス メソッドの仮想化

このパターンでは、クラス V の呼び出し元は仮想化された戻り値を受け取ります。基本的に、これは、仮想化されたメソッドがどのように (どこから) 呼び出されるかに関係なく、クラス V の動作をグローバルに変更します。

このタイプの仮想化を設定するには、完全修飾クラス名と、仮想化するメソッド名 (または記録モードの場合は記録する) メソッドの名前を指定します。仮想化モードでは、これらの指定されたメソッドの戻り値が変更されます。

呼び出しの仮想化

このパターンでは、特定のメソッドが特定の場所からどのように呼び出されるかを仮想化します。ここでは、次の情報を渡します。

このパターンは、リモート EJB メソッド呼び出しの仮想化に特に有用です。呼び出し元クラスは通常、コントローラー オブジェクトです。コントローラー オブジェクト内では、宣言されたリモート インターフェイス タイプを使用してリモート EJB 呼び出しが行われます。以下に、このパターンを使用してリモート EJB 呼び出しを仮想化する方法を図で示します。

エージェント構成

エージェントを使用するために Java アプリケーションを構成する

  1. ParasoftJavaVirtAgent.jar とその他の付随ファイルを、アプリケーションからアクセスできるファイル パスの場所にコピーします。
  2. アプリケーションの java スタートアップ実行ファイルに次の JVM 引数を追加します (各 –D 引数の前にスペースを入れて 1 行で指定します)。

    -javaagent:"C:/PathTo/ParasoftJavaVirtAgent.jar" -Dparasoft.virtualize.config="C:/Path/AgentConfig.xml" -Dparasoft.virtualize.log.config="C:/Path/logging.properties"

アプリケーションが ClassNotFoundExceptions をログに記録する場合は、次のフラグを追加してみてください。

-Xbootclasspath/a:"C:/Path/ParasoftJavaVirtAgent.jar;C:/Path/xstream-1.4.2.jar"

Oracle WebLogic 

上記の引数を追加するには、setDomainEnv.sh サーバー起動スクリプトを編集します。Xbootclasspath を設定する必要はありません。

Apache Karaf/ServiceMix

Xbootclasspath の設定が必要です。また、親クラスローダーにデリゲートされる Java パッケージも調整する必要があります。これにより、OSGi バンドルが Parasoft Agent ランタイム ライブラリに対して実行時に可視性を持つようになります。Apache Service Mix では、/etc/ ディレクトリの custom.properties ファイル内の org.osgi.framework.bootdelegation プロパティの末尾に次の内容 (すべて 1 行) を追加することで、これを実現できます。

,com.parasoft.virtualize.java.agent.runtime,com.parasoft.virtualize.java.agent.runtime.*

,com.thoughtworks.xstream.*

IBM WebSphere Application Server

サーバー起動ファイルを編集する必要はありません。IBM Integrated Solutions Console for WAS を使用してエージェントを構成できます。[Application servers] > [server name] > [Process definition] > [Java Virtual Machine] に移動します。[Generic JVM Arguments] フィールドに、エージェント設定引数を入力します。例 (すべて 1 行で、各 -D 引数はスペースで区切ります):

-javaagent:C:/Parasoft/ParasoftJavaVirtAgent.jar -Dparasoft.virtualize.config=C:/Parasoft/PlantsByWebSphere.xml -Dparasoft.virtualize.log.config=C:/Parasoft/logging.properties

-javaagent パスが誤って入力されているか、ファイルが削除されているためサーバーの起動に失敗した場合は、[was.install.root]/profiles/[profile name]/config/cells/[cellname]/nodes/[node name]/servers/server1/ ディレクトリの server.xml ファイルを編集し、不正な引数を削除することで修正できます (ParasoftJavaVirtAgent.jar または指定したその他の引数パラメーターの出現箇所を検索します)。

WebSphere Application Server は、エージェントのログ記録構成を上書きし、常に出力を独自のログ記録フレームワークにリダイレクトします。IBM Console の [Logging and Tracing] > [server1] > [Change log detail levels] で、必要なログ記録レベルを設定できます。com.parasoft.virtualize.* コンポーネントを探し、必要に応じてログ記録レベルを調整します。Parasoft Java Virtualization エージェントのログは、[was.install.root]/profiles/[profilename]/logs/[server name]/native_stdout.log にあります。

IBM WebSphere Community Edition

Xbootclasspath の設定が必要です。

仮想アセットによって制御されるエージェントの設定

JavaVirtualization.pva (zip アーカイブに含まれる) を Virtualize サーバーにデプロイし、エージェントの Virtualize サーバー URL がそのアセットを指すように設定します。このアセットは、次の操作を実行できるようになります。

以下の設定をエージェント上で構成する必要があります。

-Dparasoft.virtualize.remote.mode=true

true の場合、実行時にモードの切り替えが有効になります。この切り替えは、JavaVirtualization.pva で使用されている環境を更新することによって行われます。PVA をチェックして、適切な環境をアクティブに設定することでモードを制御できることを確認します。

logging.properties

Java ユーティリティ ログをサーバーに送信できるようにするには、これを com.parasoft.virtualize.java.agent.log.ServerHandler に設定します。

AgentConfig.xml

エージェントが記録されたトラフィックを Virtualize サーバーに送信するには、AgentConfig.xml の recorderTypeHTTP_TRAFFIC_SERVER に設定します (AgentConfig.xml の詳細については、次のセクションを参照してください)。

エージェントのログ記録の設定

エージェントには、logging.properties ファイルが含まれています。このファイルを編集することで、エージェントによって作成されるローカル ログ ファイルの詳細度と場所を設定できます。エージェントは Java の標準組み込みロギングフレームワークを使用するため、そのフレームワークに適用されるプロパティと設定がエージェントにも適用されます (http://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html を参照)。一般に、次の 2 つのプロパティを考慮する必要があります。

com.parasoft.virtualize.java.agent.level=ALL|FINEST|FINER|FINE|INFO|WARNING|SEVERE

java.util.logging.FileHandler.pattern=C:\path/parasoft_java_agent_log.%g.txt

一部のアプリケーション サーバー プラットフォームでは、エージェントの logging.properties ファイルで設定されたログ出力先とレベルが上書きされることに注意してください。このような場合は、アプリケーション サーバー独自のフレームワークを使用してログ出力レベルを調整できます。特定のサーバー構成に関する注意事項については、「エージェントを使用するために Java アプリケーションを構成する」セクション (上記) を参照してください。

デフォルトでは、アプリケーション JVM がエージェントを使用して正常に起動すると、次のログ ステートメントが表示されます。

[Parasoft Java Virtualization Agent: INFO {timestamp}] class file transformer initialized using configuration file {file path}

アプリケーションがロードされてインストルメントされると、次のログ ステートメントの 1 つ以上がデフォルトのログ出力レベル (info) で表示されます。

[Parasoft Java Virtualization Agent: INFO {timestamp}] transforming {class name provided in the agent configuration XML}

AgentConfig.xml の概要

AgentConfig.xml は、エージェント固有の XML 記述子です。エージェントに、どのクラスとメソッドを適用するか、どのモード (仮想化、記録など) を適用するかを伝えます。以下に設定ファイルの例を示します。

<ParasoftJavaVirtAgent>
	<virtualizeServer>
		<url>http://localhost:9080/ParaBankJavaLoanRequest</url>
	</virtualizeServer>
	<recorderType>HTTP_TRAFFIC_FILE</recorderType>
<localRecordingFilePath>/Users/jsmith/JavaVirt/JavaRecording.txt</localRecordingFilePath>
	<callVirtualizationClasses>
		<callVirtualizationClass>
		<callingMethods>
			<method>
				<className>com.parasoft.parabank.domain.logic.impl.BankManagerImpl</className>
				<methodName>requestLoan</methodName>
				<argumentTypes>
					<string></string>
				</argumentTypes>
				<mode>INACTIVE</mode>
			</method>
		</callingMethods>
		<virtualizedMethods>
			<method>
				<className>com.parasoft.parabank.domain.logic.LoanProvider</className>
				<methodName>requestLoan</methodName>
					<argumentTypes>
						<string></string>
					</argumentTypes>
				<mode>INACTIVE</mode>
			</method>
		</virtualizedMethods>
	</callVirtualizationClass>
</callVirtualizationClasses>
<methodVirtualizationClasses>
			<method>
		<className>com.parasoft.parabank.domain.logic.impl.ConfigurableLoanProvider</className>
			<methodName>requestLoan</methodName>
			<argumentTypes>
					<string></string>
				</argumentTypes>
				<mode>RECORD</mode>
			</method></methodVirtualizationClasses>
</ParasoftJavaVirtAgent>

エージェント構成セクション

<virtualizeServer>
	<url>http://virtServerHost:9080/ParaBankJavaLoanRequest</url>
</virtualizeServer>

このセクションは、VIRTUALIZE モードのメソッドに適用されます。Virtualize サーバーへの HTTP パスと、記録から事前に生成された PVA を示します。

<localRecordingFilePath>/Users/jsmith/JavaVirt/JavaRecording.txt</localRecordingFilePath>

このセクションは、Java メソッド呼び出しを保存する場所への絶対パスです (RECORD モードの場合)。デフォルトでは、新しいトラフィックが既存のトラフィック ファイルに追加されることに注意してください。したがって、同じ呼び出しを複数回記録すると、ファイル内のデータが重複する可能性があります。

<callVirtualizationClasses> </callVirtualizationClasses>

このセクションには、1 つ以上の <callVirtualizationClass> 要素を含めることができます。呼び出し仮想化パターンのクラスとメソッドを指定します。なお、以下を使用してメソッドの完全修飾シグネチャを指定することは

<argumentTypes><string>argTypesNYI</string></argumentTypes>

現時点ではサポートされていません。

<callingMethods> 要素は、どのメソッドから呼び出しの仮想化を適用するかを指定します。<virtualizedMethods> 要素で指定されたメソッドは、実際に仮想化されるメソッドです。

<mode> </mode>

このセクションは、指定されたメソッドに対して、3 つの値 (INACTIVE、RECORD、VIRTUALIZE) のいずれかを取ることができます。INACTIVE は、エージェントに、元のメソッドの起動を記録したり、仮想化したり、動作を変更したりせずに、元のメソッドを呼び出させるよう指示します。

<methodVirtualizationClasses>

このセクションでは、クラス メソッド仮想化パターンを適用するクラスとそのメソッドのリストを指定します。

この例からわかるように、2 つの仮想化パターンを混在させ、指定されたクラス/メソッドごとにさまざまなモードを混在させることができます。

PVA の生成

アプリケーションが目的のシナリオで実行され、一部のクラス/メソッドが RECORD モードで設定されたら、記録されたファイルをテスト対象アプリケーションから取得し、トラフィックから Virtualize の PVA 作成ウィザードに渡すことができます。

トラフィックから PVA を作成するときは、HTTP オプションを選択します (エージェントが生成した Java 記録ファイルは、オブジェクトが XML 表現に変換された HTTP トラフィック ファイルとしてフォーマットされます)。

記録された各メソッドには XML ファイル内に一意の XML ルート要素があるため、一意のメソッドごとにレスポンダーが作成されます。各レスポンダーは、記録されたさまざまな入力引数/戻り値を反映するために、"複数レスポンス" モードで作成されます。

生成された PVA の使用

PVA がデプロイされたら、AgentConfig.xml を VIRTUALIZE モードに切り替え、url 要素を PVA デプロイメントの HTTP エンドポイントに指定します。エージェントにより、アプリケーションの JVM は、実際のメソッドを呼び出す代わりに、指定されたメソッド呼び出しをリモートで Virtualize に (HTTP 経由で) リダイレクトします。Virtualize で設定されている戻りオブジェクトが、これらのメソッドの戻り値として使用されます。

前提と制限事項

Java 仮想化エージェントは、アプリケーション内の別のサブコンポーネントで何らかの機能を実行したり、リモートで何らかの依存関係を呼び出したりするステートレス メソッド呼び出しを記録および仮想化するのに特に有用です。

このリリースのエージェントを使用する際に留意すべき制約の一部を次に示します。

チュートリアル: ParaBank

クラス メソッドの仮想化

まず、ConfigurableLoanProvider クラスの動作を仮想化して、クラス メソッドの仮想化パターンを試してみましょう。このクラスは、ParaBank でどのローン プロバイダーが設定されているかに関係なく、ローンを申請するために呼び出されます。

  1. Virtualize 内で ParaBank プロジェクトを作成します。
  2. 上記の AgentConfig.xml サンプルを使用します (localRecordingFilePath を、ご使用の環境で記録ファイルを保存する場所に変更します)。
  3. ParaBank Run Configuration を開き、VM 引数を追加します (すべて 1 行で、各 –D 引数をスペースで区切ります)。

    -javaagent:"C:\PATH\ParasoftJavaVirtAgent.jar" -Dparasoft.virtualize.config="C:\PATH\AgentConfig.xml" -Dparasoft.virtualize.log.config="C:\PATH\logging.properties"
  4. このラン コンフィギュレーションを実行し、以下のようにアプリケーションを実行します。
    1. ユーザー名 john とパスワード demo を使用して ParaBank にログインします。
    2. [Request Loan] をクリックします。
    3. 元金 1000、頭金 200 のローンを申請します。
    4. 頭金 100 で 10000 の別のローンを申請します。
  5. ローカル RecordingFilePath で指定した場所にファイルが作成されたことを確認します。
  6. ParaBank をシャットダウンします。

  7. 次のようにトラフィックから新しい PVA を作成します。
    1. [トラフィック] > [固定メッセージの生成] を選択し、トラフィック ファイルの場所を指定して [次へ] をクリックします。 
    2. メッセージのグループ化で [操作/タイプに基づく] を選択し、[次へ] をクリックします。
    3. メッセージ グループ化の確認中に、次のステップでリクエストのマッチング オプションを手動で構成するために [自動設定] を無効にし、[次へ] をクリックします。
    4. リクエストの照合中に、既存のパラメーターを削除し、リクエスト本体の関連パラメーターとして loanAmount 要素と downPayment 要素のみを追加し、[次​​へ] をクリックします。
    5. AgentConfig.xml にあるものと一致するデプロイメント エンドポイントを指定します。ここでは次を使用します:

      /ParaBankJavaLoanRequest

      <virtualizeServer>
      	<url>http://localhost:9080/ParaBankJavaLoanRequest</url>
      </virtualizeServer>
    6. [終了] をクリックします。
      PVA は 複数レスポンス モードで 1 つのレスポンダーを使用して作成されます。この例では 1 つのメソッドだけを仮想化しているため、レスポンダーは 1 つしか作成されません。
  8. 次のコードを追加してレスポンスを編集します:  <loanProviderName>Parasoft Virtualize</loanProviderName> 
  9. AgentConfig.xml のモードを VIRTUALIZE に切り替えます。

    <methodVirtualizationClasses>
    <method>
    <className>com.parasoft.parabank.domain.logic.impl.ConfigurableLoanProvider</className>
    	<methodName>requestLoan</methodName>
    	<argumentTypes>
    		<string></string>
    	</argumentTypes>
    	<mode>VIRTUALIZE</mode>
    </method>
    </methodVirtualizationClasses>
  10. ParaBank を再度実行して、前回記録したのと同じ金額でローンを申請します。Virtualize レスポンダーで指定した内容が Loan Provider ラベルに表示される点に注意してください。Virtualize 内で仮想アセットのモニタリングを有効にすると、ParaBank によって生成され、Virtualize によって受信されたリクエストとレスポンスを確認できます。

呼び出しの仮想化

次に、呼び出しの仮想化パターンを試してみましょう。この演習の目標は、BankManagerImpl.java のメソッド requestLoan() の次の呼び出し行を仮想化することです。

LoanResponse loanResponse = loanProvider.requestLoan(loanRequest);

そのためには、エージェントに次のことを指示する必要があります。

呼び出し仮想化パターンを試すには、次の操作を行います。

  1. クラス メソッドの仮想化を INACTIVE に設定します。

    <methodVirtualizationClasses>
    <method>
    <className>com.parasoft.parabank.domain.logic.impl.ConfigurableLoanProvider</className>
    	<methodName>requestLoan</methodName>
    	<argumentTypes>
    		<string></string>
    	</argumentTypes>
    	<mode>INACTIVE</mode>
    </method>
    </methodVirtualizationClasses>
  2. 呼び出し Virtualization クラス モードを RECORD に設定します。

    <callVirtualizationClass>
    	<callingMethods>
    		<method>
    			<className>com.parasoft.parabank.domain.logic.impl.BankManagerImpl</className>
    			<methodName>requestLoan</methodName>
    			<argumentTypes>
    				<string></string>
    			</argumentTypes>
    			<mode>RECORD</mode>
    		</method>
    	</callingMethods>
    <virtualizedMethods>
    		<method>
    			<className>com.parasoft.parabank.domain.logic.LoanProvider</className>
    			<methodName>requestLoan</methodName>
    			<argumentTypes>
    				<string></string>
    			</argumentTypes>
    			<mode>RECORD</mode>
    		</method>
    	</virtualizedMethods>
    </callVirtualizationClass>
  3. ParaBank を実行してローン金額をリクエストします。前の演習のステップ 4 から 7 を繰り返します。
  4. callVirtualizationClass セクションのモードを VIRTUALIZE に切り替えます。
  5. ParaBank を再度実行します。メソッド呼び出しをエミュレートするために Virtualize が使用されるようになったことに注目してください。