はじめに
ケント・ベックらが提唱したエクストリームプログラミング(XP)と呼ばれる開発手法が広まり、「テストファースト-コードを記述する前にテストコードを書く」というテスト手法が非常に多くのプロジェクトで導入されています。テストコードを記述するためのAPIとしてJUnitが最も多く用いられていますが、JUnitだけではServletやJSPなど、サーブレットコンテナを必要とするコードをテストできません。本稿では、Jakartaプロジェクトで開発が進められているCactusを取り上げ、主にServletのコードをテストする手法について解説します。
対象読者
J2EEアプリケーションの開発者。JUnit経験者。
環境
本稿では、Cactusとサンプルアプリケーションが正しく動作する環境が必要になります。必要なものを以下の表にまとめました。なお、J2SE、Tomcatの基本的な環境設定について知りたい方は、「サーバサイド技術の学び舎 - WINGS」にある「サーバサイド環境構築設定」を参照してください。
ライブラリ | バージョン | ダウンロード元 |
J2SE | 5.0 | http://java.sun.com/j2se/1.5.0/download.jsp |
Ant | 1.6.5 | http://ant.apache.org/bindownload.cgi |
Tomcat | 5.5.12 | http://tomcat.apache.org/download-55.cgi |
Cactus | 1.7.2 | http://jakarta.apache.org/site/downloads/downloads_cactus.cgi |
Cactusの概要とアーキテクチャ
CactusはJUnitだけではテストできない、Servlet、JSP、Filterなどをテストするためのテストフレームワークであり、Jakartaプロジェクトによって開発が進められています。Cactusの設定/利用方法の前に、まずは簡単に仕組みについて解説します。Cactusを利用せずにServletをテストするには、次のような手順で行うことが多いでしょう。
- Webアプリケーションをサーブレットコンテナ(Tomcatなど)にデプロイする
- クライアントのブラウザから、Webアプリケーションに対してリクエストを送信する
- 指定されたServletが実行され、処理結果(レスポンス)をクライアントに返す
- 処理結果(レスポンス)をブラウザで視認する
この2)、4)のブラウザからリクエストの送信&処理結果(レスポンス)を視認するというところが厄介で、大規模なWebアプリケーションであるほど、テストにかけるコストは膨大なものになります。Cactusでは、この作業をJUnitのように記述することにより、自動化させることができます。Cactusの動作の仕組みについては、以下の処理フロー図を見ながら簡単に解説します。
beginXXX()
で初期化処理を行う- Redirector Proxyに対してHTTPリクエストを送信する
- Redirector Proxyが受けたリクエストを元に、対象のテストコードを呼び出す
- テストクラスに定義された
setUp()
、testXXX()
、tearDown()
メソッドが、順番に呼び出される - テストクラスがServletなどのサーバーサイドクラスを実行する
- テスト結果をRedirector Proxyが受け取る
- ServletのレスポンスをRedirector Proxyから受け取る
- 再びRedirector Proxyに対してHTTPリクエストを送信する
- クライアントがテスト結果を受け取る
endXXX()
で後処理を行う
クライアントとサーバー間のHTTP通信を、Redirector Proxyと呼ばれるオブジェクトが制御し、処理を行っています。Redirector Proxyには、Servlet Redirector、JSP Redirector、Filter Redirectorの3種類があり、それぞれ、Servlet、JSP、Filterをテストするように使い分けられます。
サンプルアプリケーションのディレクトリ構成
サンプルアプリケーションのディレクトリ構成図を以下に記述します。srcにあるものを、antツールを使ってwarファイルに、テスト結果レポートなどをtargetにそれぞれ生成するようにしています。
|- - cactus-sample | |- - lib cactus、サンプルアプリケーションで参照するJar | |- - src ソース |- - java サンプルアプリケーションのソース |- - test-cactus サンプルアプリケーションのテストソース |- - webapp Webアプリケーションのファイル(JSP、web、xmlなど) |- - target - srcからの生成結果
Cactusの基本的な設定
次に、Cactusでテストを行うための基本的な環境設定について解説します。基本的に設定ファイルはCactusのバイナリをダウンロードした際に含まれているものを書き換える形で使用しています。以下が環境設定に必要なファイルの表です。
ファイル名 | 概要 |
build.properties | cactusで利用するコンテナの設定 |
build.xml | buildとcactusの動作の設定 |
build.properties
「build.properties」では、テストを行うためのコンテナの環境設定を行います。プロパティを以下の表にまとめました。
プロパティ名 | 概要 |
cactus.port | cactusのテストで使用するサーブレットコンテナのポート番号(設定がなければ8080) |
cactus.home.xxx | cactusのテストで使用するサーブレットコンテナの種類とそのディレクトリ(使用するサーブレットコンテナのうち、各種類のプロパティのコメントアウトを外して設定する) |
今回はtomcat 5.5.12を使用し、8080番のポート番号でテストを行う設定にします。まず、cactus.portは8080のデフォルトポート番号なので設定する必要はありません。次に、サーブレットコンテナとしてもtomcat 5.5.12を使用するので、cactus.hometomcat5xのコメントアウトを外し、実行環境のディレクトリに書き換えます。次のように、実際には修正しています。
# The port to use for starting the servers during unit testing. If not # specified, it defaults to port 8080. #cactus.port = 8081 # Servlet engine locations for the tests # Note: If you don't want to run the test on a given servlet engine, just # comment it's home property. For example, if you don't want to run the # tests on the Resin 2.x, comment the "cactus.home.resin2x" property. #cactus.home.resin2x = c:/Apps/resin-2.1.14 #cactus.home.resin3x = c:/Apps/resin-3.0.9 #cactus.home.tomcat4x = c:/Apps/jakarta-tomcat-4.1.31 cactus.home.tomcat5x = D:/apache-tomcat-5.5.12 #cactus.home.orion1x = c:/Apps/orion-1.6.0b #cactus.home.orion2x = c:/Apps/orion-2.0.4 #cactus.home.jboss3x = c:/Apps/jboss-3.2.6 #cactus.home.weblogic7x = c:/bea/weblogic700
build.xml
「build.xml」は、標準では正しい設定になっていないため修正を行います。まず、target=testの中の、containerset
タグの中のtomcat5x
タグの要素に、serverxml
属性の指定が必要なため、修正を行います。
<!-- 修正前 --> <tomcat5x if="cactus.home.tomcat5x" dir="${cactus.home.tomcat5x}" port="${cactus.port}" output="${target.testreports.dir}/tomcat5x.out" todir="${target.testreports.dir}/tomcat5x" /> <!-- 修正後 --> <tomcat5x if="cactus.home.tomcat5x" dir="${cactus.home.tomcat5x}" port="${cactus.port}" output="${target.testreports.dir}/tomcat5x.out" todir="${target.testreports.dir}/tomcat5x" serverxml="${cactus.home.tomcat5x}/conf/server.xml" />
さらに、同じくtarget=testの中の、batchtest
タグの中で、実行対象となるテストクラスを指定しています。標準では、特定のパッケージの下のTestXXX
クラスのみを対象となるようにしているので、修正します。
<!-- 修正前 --> <batchtest> <fileset dir="${src.cactus.dir}"> <!-- Due to some Cactus synchronization bug, the 'unit' tests need to run before the 'sample' tests --> <include name="**/servlet/unit/Test*.java"/> <exclude name="**/servlet/unit/Test*All.java"/> </fileset> </batchtest> <!-- 修正後 --> <batchtest> <fileset dir="${src.cactus.dir}"> <!-- Due to some Cactus synchronization bug, the 'unit' tests need to run before the 'sample' tests --> <include name="**/Test*.java"/> </fileset> </batchtest>
基本的にこれで実行できます。通常の「build.xml」と比べて変わっている点として、テスト結果をレポートとして出力する設定なども記述してありますが、特に設定を書き換える必要はないでしょう。
また、Cactusで参照されるJarファイルの参照先も「build.xml」に記述されているため、参照先を換える場合には変更が必要です。主にCactusが参照するJarファイルを以下の表にまとめました。
Jar | 概要 |
cactus.jar | cactusのコアとなるjar |
cactus-ant.jar | antでcactusのテストを実行するためのjar |
httpclient.jar | jakarta-commonsのhttpclient.jarと同じ。クッキーを利用するテストなどで使用 |
junit.jar | cactusはjunitを拡張したものなので必要 |
aspectjrt.jar | ログ出力などでアスペクト指向プログラミングのAspectJのjarを使用 |
log4j.jar | ログ出力を行うためのjar |