2.3. リクエスト単体テスト(ウェブアプリケーション)¶
2.3.1. 概要¶
リクエスト単体テスト(ウェブアプリケーション)では、内蔵サーバを使用してテストを行う。ここでは、リクエスト単体テストのテスト補助クラスと内蔵サーバの使用方法を記載する。
2.3.1.1. 全体像¶
2.3.1.2. 主なクラス, リソース¶
名称 | 役割 | 作成単位 |
---|---|---|
テストクラス | テストロジックを実装する。 | テスト対象クラス(Action)につき1つ作成 |
テストデータ(Excelファイル) | テーブルに格納する準備データや期待する結果、HTTPパラメータなど、テストデータを記載する。 | テストクラスにつき1つ作成 |
テスト対象クラス(Action) | テスト対象のクラス (Action以降の業務ロジックを実装する各クラスを含む) | 取引につき1クラス作成 |
DbAccessTestSupport | 準備データ投入などデータベースを使用するテストに必要な機能を提供する。 | - |
HttpServer | 内蔵サーバ。サーブレットコンテナとして動作し、HTTPレスポンスをファイル出力する機能を持つ。 | - |
HttpRequestTestSupport | 内蔵サーバの起動やリクエスト単体テストで必要となる各種アサートを提供する。 | - |
AbstractHttpReqestTestSupport BasicHttpReqestTestSupport |
リクエスト単体テストをテンプレート化するクラス。リ クエスト単体テストのテストソース、テストデータを定 型化する | - |
TestCaseInfo | データシートに定義されたテストケース情報を格納する クラス。 |
上記のクラス群は、内蔵サーバも含め全て同一のJVM上で動作する。このため、リクエストやセッション等のサーバ側のオブジェクトを加工できる。
2.3.1.3. 前提事項¶
内蔵サーバを利用してHTMLダンプを出力するというリクエスト単体テストは、1リクエスト1画面遷移のシンクライアント型ウェブアプリケーションを対象としている。Ajaxやリッチクライアントを利用したアプリケーションの場合、HTMLダンプによるレイアウト確認は使用できない。
ちなみに
本書ではViewテクノロジにJSPを用いているが、サーブレットコンテナ上で画面全体をレンダリングする方式であれば、JSP以外のViewテクノロジでもHTMLダンプの出力が可能である。
2.3.2. 構造¶
2.3.2.1. BasicHttpRequestTestTemplate¶
各テストクラスのスーパクラス。本クラスを使用することで、リクエスト単体テストのテストソース、テストデータを定型化でき、テストソース記述量を大きく削減できる。
具体的な使用方法は、リクエスト単体テストの実施方法を参照。
2.3.2.2. AbstractHttpRequestTestTemplate¶
アプリケーションプログラマが直接使用することはない。テストデータの書き方を変えたい場合など、自動テストフレームワークを拡張する際に用いる。
2.3.2.3. TestCaseInfo¶
データシートに定義されたテストケース情報を格納するクラス。テストデータの書き方を変えたい場合は、本クラス及び前述のAbstractHttpRequestTestTemplateを継承する。
2.3.2.4. HttpRequestTestSupport¶
リクエスト単体テスト用に用意されたスーパクラス。リクエスト単体テスト用のメソッドを用意している。
2.3.2.4.1. データベース関連機能¶
データベースに関する機能は、DbAccessTestSupportクラスに委譲することで実現している。 詳細は、データベースを使用するクラスのテストを参照。
ただし、DbAccessTestSupportのうち以下のメソッドは、リクエスト単体テストでは不要であり、アプリケーションプログラマに誤解を与えないよう、意図的に委譲を行っていない。
- public void beginTransactions()
- public void commitTransactions()
- public void endTransactions()
- public void setThreadContextValues(String sheetName, String id)
2.3.2.4.2. 事前準備補助機能¶
内蔵サーバへのリクエスト送信には、HttpRequestとExecutionContextのインスタンスが必要となる。HttpRequestTestSupportクラスでは、これらのオブジェクトを簡単に作成できるようメソッドを用意している。
2.3.2.4.2.1. HttpRequest¶
HttpRequest createHttpRequest(String requestUri, Map<String, String[]> params)
引数には、以下の値を引き渡す。
- テスト対象となるリクエストURI
- 上記で取得したリクエストパラメータ
本メソッドでは、受け取ったたリクエストURIとリクエストパラメータを元にHttpRequestインスタンスを生成し、HTTPメソッドをPOSTに設定した上で返却する。HttpRequestにリクエストパラメータやURI以外のデータを設定したい場合は、本メソッド呼び出しにより取得したインスタンスに対してデータの設定を行うとよい。
2.3.2.4.2.2. ExecutionContext¶
ExecutionContextインスタンスを生成する。
ExecutionContext createExecutionContext(String userId)
引数にはユーザIDを指定する。指定したユーザIDはセッションに格納される。これにより、そのユーザIDでログインしている状態となる。
2.3.2.4.2.3. トークン発行¶
2重サブミット防止を施しているURIに対するテストを行うには、テスト実行前にトークンを発行しセッションに設定しておく必要がある。HttpRequestTestSupportにある下記のメソッドを呼び出すことで、トークンの発行およびセッションへの格納が行われる。
void setValidToken(HttpRequest request, ExecutionContext context)
リクエスト単体実行時に、テストデータ上でトークンを設定するか否かを制御したい場合は、 以下のメソッドを使用する。
void setToken(HttpRequest request, ExecutionContext context, boolean valid)
第3引数がbooleanになっており、真の場合は前述のsetValidTokenと同じ動作となる。 偽の場合は、セッションからトークン情報が除去される。以下のように使用することで、 テストクラスにトークンを設定するかどうかの分岐処理を書かなくてすむ。
// 【説明】テストデータから取得したものとする。
String isTokenValid;
// 【説明】"true"の場合はトークンが設定される。
setToken(req, ctx, Boolean.parseBoolean(isTokenValid)));
2.3.2.5. 実行¶
HttpRequestTestSupportにある下記のメソッドを呼び出すことで、内蔵サーバが起動されリクエストが送信される。
HttpResponse execute(String caseName, HttpRequest req, ExecutionContext ctx)
引数には以下の値を引き渡す。
- テストケース説明
- HttpRequest
- ExectionContext
テストケース説明は、HTMLダンプ出力時のファイル名に使用される。 詳細は HTMLダンプ出力ディレクトリ を参照。
2.3.2.6. 結果確認¶
2.3.2.6.1. メッセージ¶
HttpRequestTestSupportにある下記のメソッドを呼び出すことで、アプリケーション例外に格納されたメッセージが想定通りであることを確認する。
void assertApplicationMessageId(String expectedCommaSeparated, ExecutionContext actual);
引数には、以下の値を引き渡す。
- 期待するメッセージ(複数ある場合はカンマ区切りで指定する。)
- 先に作成したExectionContext
例外が発生しなかった場合や、アプリケーション例外以外の例外が発生した場合は、アサート失敗となる。
ちなみに
メッセージIDの比較はIDをソートした状態で行うので、テストデータを記載する際に 順序を気にする必要はない。
2.3.2.7. HTMLダンプ出力¶
2.3.2.7.1. HTMLダンプ出力ディレクトリ¶
テストを実行すると、テスト用プロジェクトのルートディレクトリにtmp/html_dumpディレクトリが作成される。 その配下にテストクラス毎に同名のディレクトリが作成され、 そのテストクラスで実行されたテストケース説明と同名のHTMLダンプファイルが出力される。
また、HTMLダンプファイルが参照するHTMLリソース(スタイルシートや画像などのリソース)についても このディレクトリに出力されるので、このディレクトリを保存することで、どの環境でもHTMLを同じように参照できる。
- html_dumpディレクトリが既に存在する場合は、html_dump_bkという名前でバックアップされる。
2.3.3. 各種設定値¶
環境設定に依存する設定値については、コンポーネント設定ファイルで変更できる。設定可能な項目を以下に示す。
2.3.3.1. コンポーネント設定ファイル設定項目一覧¶
設定項目名 | 説明 | デフォルト値 |
---|---|---|
htmlDumpDir | HTMLダンプファイルを出力するディレクトリを指定する。 | ./tmp/http_dump |
webBaseDir | ウェブアプリケーションのルートディレクトリ[1] | ../main/web |
xmlComponentFile | リクエスト単体テスト実行時に使用するコンポーネント設定ファイル[2] | (なし) |
userIdSessionKey | ログイン中ユーザIDを格納するセッションキー | user.id |
exceptionRequestVarKey | ApplicationExceptionが格納されるリクエストスコープのキー | nablarch_application_error |
dumpFileExtension | ダンプファイルの拡張子 | html |
httpHeader | HttpRequestにHTTPリクエストヘッダとして格納される値 | Content-Type : application/x-www-form-urlencoded Accept-Language : ja JP |
sessionInfo | セッションに格納される値 | (なし) |
htmlResourcesExtensionList | ダンプディレクトリへコピーされるHTMLリソースの拡張子 | css、jpg、js |
jsTestResourceDir | javascriptの自動テスト実行時に使用するリソースのコピー先ディレクトリ名 | ../test/web |
backup | ダンプディレクトリのバックアップOn/Off | true |
htmlResourcesCharset | CSSファイル(スタイルシート)の文字コード | UTF-8 |
checkHtml | HTMLチェックの実施On/Off | true |
htmlChecker | HTMLチェックを行うオブジェクトを指定する。 オブジェクトは nablarch.test.tool.htmlcheck.HtmlChecker インタフェースを実装している必要がある。 詳細は HTMLチェック内容の変更 を参照。 |
nablarch.test.tool.htmlcheck.Html4HtmlChecker
クラスのインスタンス。 クラスには htmlCheckerConfig で設定した設定 ファイルが適用される。 |
htmlCheckerConfig | HTMLチェックツールの設定ファイルパス。 htmlChecker を設定しなかった場合のみ有効。 |
test/resources/httprequesttest/html-check-config.csv |
ignoreHtmlResourceDirectory | HTMLリソースの中でコピー対象外とするディレクトリ名のLIST ちなみに バージョン管理用のディレクトリ(.svnや.git)を対象外と設定すると HTMLリソースコピー時のパフォーマンスが向上する。 |
(なし) |
tempDirectory | JSPのコンパイル先ディレクトリ | jettyのデフォルト動作に依存 ちなみに jettyのデフォルト動作では、.「/work」 がコンパイル先ディレクトリとなる。 「./work」が存在しない場合は、 Tempフォルダ(Windownの場合は、ユーザのホーム ディレクトリ/Local Settings/Temp)が 出力先となる。 |
uploadTmpDirectory | アップロードファイルを一時的に格納するディレクトリ。 テスト時に準備した、アップロード対象のファイルは本ディレクトリに コピー後に処理される。 これにより、アクションでファイルの移動を行った場合でも、 本ディレクトリ配下のファイルが移動されるだけであり、 実態が移動されることを防ぐことができる。 |
./tmp |
dumpVariableItem | HTMLダンプファイル出力時に可変項目を出力するか否かを設定する。 ここでの可変項目とは以下の2種類を指す。
これらの項目は、テスト実行毎に異なる値が設定される。 HTMLダンプ結果を毎回同じ結果にしたい場合は、本項目をOFF (false)に設定する。(前回実行結果と差異がないことを確認したい場合等) 可変項目をそのままHTMLに出力する場合は、本項目をON (true)に設定する。 |
false |
[1] | PJ共通のwebモジュールが存在する場合、このプロパティにカンマ区切りでディレクトリを設定する。 複数指定された場合、先頭から順にリソースが読み込まれる。 以下に例を示す。 <component name="httpTestConfiguration" class="nablarch.test.core.http.HttpTestConfiguration">
<property name="webBaseDir" value="/path/to/web-a/,/path/to/web-common"/>
この場合、web-a、web-commonの順にリソースが探索される。 |
[2] | この項目を設定した場合は、リクエスト送信直前に指定されたコンポーネント設定ファイルで初期化が行われる。通常は設定する必要はない。クラス単体テストとリクエスト単体テストとで設定を変える必要がある場合のみ、この項目を設定する。 |
2.3.3.2. コンポーネント設定ファイルの記述例¶
コンポーネント設定ファイル記述例を記載する。 設定値には、上記のデフォルト値に加え、セッション(sessionInfo)に以下の値を設定している。
キー | 値 | 説明 |
---|---|---|
commonHeaderLoginUserName | “リクエスト単体テストユーザ” | 共通ヘッダ領域に表示するログインユーザ名 |
commonHeaderLoginDate | “20100914” | 共通ヘッダ領域に表示するログイン日時 |
<component name="httpTestConfiguration" class="nablarch.test.core.http.HttpTestConfiguration">
<property name="htmlDumpDir" value="./tmp/http_dump"/>
<property name="webBaseDir" value="../main/web"/>
<property name="xmlComponentFile" value="http-request-test.xml"/>
<property name="userIdSessionKey" value="user.id"/>
<property name="httpHeader">
<map>
<entry key="Content-Type" value="application/x-www-form-urlencoded"/>
<entry key="Accept-Language" value="ja JP"/>
</map>
</property>
<property name="sessionInfo">
<map>
<entry key="commonHeaderLoginUserName" value="リクエスト単体テストユーザ"/>
<entry key="commonHeaderLoginDate" value="20100914" />
</map>
</property>
<property name="htmlResourcesExtensionList">
<list>
<value>css</value>
<value>jpg</value>
<value>js</value>
</list>
</property>
<property name="backup" value="true" />
<property name="htmlResourcesCharset" value="UTF-8" />
<property name="ignoreHtmlResourceDirectory">
<list>
<value>.svn</value>
</list>
</property>
<property name="tempDirectory" value="webTemp" />
<property name="htmlCheckerConfig"
value="test/resources/httprequesttest/html-check-config.csv" />
</component>
2.3.3.3. その他の設定¶
性能が高くないPCで開発をしており、リクエスト単体テスト実行速度を向上させたい場合は、以下の設定をすることで実行速度の改善が見込まれる。
ちなみに
Pentium4、Pentinum Dual-Core等の処理性能が低いCPUを搭載したPCに効果がある。逆に、これら以降のCPUを搭載したマシンでは、それほど効果的ではないので無理に設定する必要はない。
2.3.3.3.1. JVMオプションの指定¶
最大ヒープサイズと最小ヒープサイズを同一の値にすることで、ヒープサイズ拡張のオーバヘッドを回避できる。
-Xms256m -Xmx256m
また、クラスファイルの検証を省略することで実行速度が向上する。
-Xverfiy:none
Eclipseでの設定方法は以下のとおり。
- メニューバーより「実行」→「実行構成」を選択する。
- 「実行構成」ウィンドウが表示されるので、「引数」タブをクリックし、「VM引数」欄に前述のオプションを指定する。
また、実行構成を変更しなくても、以下の方法でデフォルトのVM引数を設定できる。
- メニューバーより「ウィンドウ」→「設定」を選択する。 「設定」ウィンドウが表示されるので、「インストール済みのJRE」をする。
- インストール済みのJREの一覧が表示されるので、使用するJREを選択し「編集」ボタンを押下する。
- 「VM引数」欄に前述のオプションを指定する。
2.3.3.3.2. 代替JREの指定¶
JavaSE5のJDKで開発を行っている場合、テスト実行時のみJavaSE6のJREを使用することにより、 実行速度、特に起動速度が向上する。
Eclipseでの設定方法は以下のとおり。
- メニューバーより「実行」→「実行構成」を選択する。
- 「実行構成」ウィンドウが表示されるので、「JRE」タブをクリックし「代替JRE」にJavaSE6のJREを選択する。
ちなみに
この設定を行う場合は、事前にJavaSE6のJDKまたはJREをインストールし、Eclipseに「インストール済みのJRE」として登録しておく必要がある。
2.3.3.3.3. HTMLリソースコピーの抑止¶
リクエスト単体実行時に、以下のシステムプロパティを指定すると、 HTMLダンプ出力 時に、HTMLリソースコピーを抑止することができる。
-Dnablarch.test.skip-resource-copy=true
CSSや画像ファイルなど静的なHTMLリソースを頻繁に編集しない場合は、 テスト実行の度にHTMLリソースをコピーする必要はないので、 このシステムプロパティを設定してもよい。
重要
本システムプロパティを指定した場合、HTMLリソースのコピーが行われなくなるので、 CSSなどのHTMLリソースを編集してもHTMLダンプ出力に反映されない。
ちなみに
HTMLリソースディレクトリが存在しない場合は、システムプロパティの設定有無に関わらず、HTMLリソースのコピーが実行される。
Eclipseでの設定方法は以下のとおり。
- メニューバーより「実行」→「実行構成」を選択する。
- 「実行構成」ウィンドウが表示されるので、「引数」タブをクリックし、「VM引数」欄に前述のオプションを指定する。