Webのユニットテスト⑩ Java
前回の続きです。
いろいろなブラウザでのユニットテストを実行する、Hudsonの分散プロジェクトを作ってみます。
の続編です。
build.xmlなどを置く
以前に作ったbuild.xml等を「【SampleJob】WEB+DBユニットテスト(Java)①デプロイ」のプロジェクト直下に置きます。
build.properties
build.xml
codeAnalysis.properties
codeAnalysis.xml
coverage.properties
coverage.xml
以下のファイルを変更しています。
■build.properties
################################################### # ディレクトリ定義 ################################################### # ソースファイル格納ディレクトリ src.dir=src # テストソースファイル格納ディレクトリ test.dir=testsrc # スタブソース格納ディレクトリ stub.dir=stubsrc # クラスファイル格納ディレクトリ class.dir=bin # ライブラリ格納ディレクトリ lib.dir=WebContent/WEB-INF/lib # テスト用ライブラリ格納ディレクトリ test.lib.dir=testlib # WARファイル格納ディレクトリ war.dir=war # 設定ファイル格納ディレクトリ conf.dir=conf # 画像ファイル格納ディレクトリ img.dir=img # スクリーンショット格納ディレクトリ screenshot.dir=screenshot # テスト結果ファイル格納ディレクトリ report.dir=report ################################################### # コンパイル定義 ################################################### # ソースファイルのエンコーディング src.encoding=UTF8 ################################################### # WARファイル作成定義 ################################################### # WARファイル名 war.name=WebAndDbUnitSample.war # WARファイルに含めるファイル create.war.src.dir.includes=**/*.xml, **/*.properties # WARファイルに含めないファイル create.war.class.dir.excludes=**/*Test*, **/Xls*, **/Stub*, **/*Assert* ################################################### # ユニットテスト実行定義 ################################################### # ユニットテスト対象外のソースファイル unitTest.test.dir.exclude=**/*Tester.java, **/*TestUtils.java, **/*Assert*.java # SeleniumServerのJARファイル seleniumServer.jar=selenium-server.jar # SeleniumServer停止URL stop.seleniumServer.url=http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer
■build.xml
SeleniumServerの起動/停止とWebTester.propertiesのコピー処理を追加しています。
WebTester.propertiesのコピー処理で使用するBrowserTypeは、Hudsonで設定した構成軸の値が入ってきます。
<?xml version="1.0" encoding="UTF-8"?> <project name="UnitTestProject" default="build" basedir="."> <!-- ========================================================== --> <!-- 定義値 --> <!-- ========================================================== --> <!-- プロパティファイル名 --> <property file="build.properties" /> <!-- ソース参照 --> <path id="build.src"> <pathelement path="${src.dir}" /> <pathelement path="${test.dir}" /> <!-- 【プロジェクト参照をする場合はココにソース参照を追加】 --> </path> <!-- ライブラリ参照 --> <path id="build.classpath"> <fileset dir="${lib.dir}" includes="**/*" /> <fileset dir="${test.lib.dir}" includes="**/*" /> <!-- 【プロジェクト参照をする場合はココにライブラリ参照を追加】 --> </path> <!-- ========================================================== --> <!-- Antタスク実行順序 --> <!-- ========================================================== --> <target name="build"> <echo message="OS:${os.name} Java:${ant.java.version} Ant:${ant.version}"/> <antcall target="clean" /> <antcall target="compile" /> <antcall target="create.war" /> <ant antfile="coverage.xml" target="build" inheritAll="true" inheritRefs="true" /> </target> <target name="build-unitTest"> <antcall target="clean-unitTest" /> <antcall target="unitTest" /> </target> <target name="build-unitTest-coverage"> <antcall target="clean-unitTest" /> <antcall target="update.WebTester.properties" /> <antcall target="unitTest" /> <ant antfile="coverage.xml" target="coverageReport" inheritAll="true" inheritRefs="true" /> </target> <!-- ========================================================== --> <!-- ディレクトリをクリア --> <!-- ========================================================== --> <target name="clean"> <delete dir="${class.dir}" /> <delete dir="${war.dir}" /> <mkdir dir="${class.dir}" /> <mkdir dir="${war.dir}" /> </target> <!-- ========================================================== --> <!-- ディレクトリをクリア(ユニットテスト用) --> <!-- ========================================================== --> <target name="clean-unitTest"> <delete dir="${report.dir}" /> <delete dir="${screenshot.dir}" /> <mkdir dir="${report.dir}" /> <mkdir dir="${screenshot.dir}" /> </target> <!-- ========================================================== --> <!-- コンパイル --> <!-- ========================================================== --> <target name="compile"> <javac destdir="${class.dir}" encoding="${src.encoding}" debug="on" includeantruntime="no" failonerror="false"> <src refid="build.src" /> <classpath refid="build.classpath" /> </javac> <copy todir="${class.dir}"> <fileset dir="${src.dir}" includes="${create.war.src.dir.includes}"/> <fileset dir="${test.dir}" includes="${create.war.src.dir.includes}"/> </copy> </target> <!-- ========================================================== --> <!-- WARファイル作成 --> <!-- ========================================================== --> <target name="create.war"> <war destfile="${war.dir}/${war.name}" webxml="WebContent/WEB-INF/web.xml"> <fileset dir="WebContent"/> <webinf dir="WebContent/WEB-INF"/> <lib dir="${lib.dir}"/> <classes dir="${class.dir}" excludes="${create.war.class.dir.excludes}" /> <classes dir="${src.dir}" includes="${create.war.src.dir.includes}"/> </war> </target> <!-- ========================================================== --> <!-- プロパティファイルの更新 --> <!-- ========================================================== --> <target name="update.WebTester.properties" if="BrowserType"> <echo message="BrowserType=${BrowserType}" /> <copy file="${test.dir}/${BrowserType}-WebTester.properties" tofile="${class.dir}/WebTester.properties" overwrite="true" /> </target> <!-- ========================================================== --> <!-- ユニットテスト実行 --> <!-- ========================================================== --> <target name="unitTest"> <!-- SeleniumServer起動 --> <java jar="${seleniumServer.jar}" fork="true" spawn="true" /> <!-- ユニットテスト実行 --> <junit fork="yes" maxmemory="512m" printsummary="on"> <classpath location="${class.dir}" /> <classpath refid="build.classpath" /> <formatter type="xml" /> <batchtest fork="yes" todir="${report.dir}"> <fileset dir="${test.dir}" excludes="${unitTest.test.dir.exclude}" /> </batchtest> </junit> <!-- SeleniumServer停止 --> <get src="${stop.seleniumServer.url}" dest="result.txt" ignoreerrors="true" /> </target> </project>
■coverageSave.jsp
Cobertura FAQによると、
アプリケーションサーバ上でカバレッジを取得する場合は、明示的にカバレッジデータの保存を実行する必要があります。
(アプリケーションサーバのプロセスはずっと動きっぱなしなので・・・カバレッジデータを保存するタイミングがないらしいです)
なので、カバレッジデータの保存を実行するJSPを作成して、Antからキックすることにします。
<% try { String className = "net.sourceforge.cobertura.coveragedata.ProjectData"; String methodName = "saveGlobalProjectData"; Class saveClass = Class.forName(className); java.lang.reflect.Method saveMethod = saveClass.getDeclaredMethod(methodName, new Class[0]); saveMethod.invoke(null,new Object[0]); } catch (Throwable t) { } %>
■coverage.properties
################################################### # カバレッジ作成定義 ################################################### # Coberturaインストールディレクトリ cobertura.home=C:/Cobertura1.9.4.1 # カバレッジデータファイル coverage.data=C:/Tomcat6.0/cobertura.ser # クラスファイル格納ディレクトリ(カバレッジ測定用) instrument.class.dir=instrument # カバレッジ測定結果出力ディレクトリ cobertura.report=coverageReport # カバレッジ測定対象外のクラス instrument.class.dir.excludes=**/*Test*, **/*Assert* # カバレッジ保存URL coverage.save.url=http://localhost:8080/TEST-WebAndDbUnitSample/coverageSave.jsp
■coverage.xml
テスト用のWARファイルにcoverageSave.jspを含めるように変更しました。
coverageSave.jspをキックして、アプリケーションサーバ上のカバレッジデータを保存する処理を追加しています。
<?xml version="1.0" encoding="UTF-8"?> <project name="UnitTestCoverage" default="coverage" basedir="."> <!-- ========================================================== --> <!-- 定義値 --> <!-- ========================================================== --> <!-- プロパティファイル名 --> <property file="build.properties" /> <property file="coverage.properties" /> <!-- カバレッジ測定用ライブラリ参照 --> <path id="cobertura.classpath"> <fileset dir="${cobertura.home}"> <include name="cobertura.jar" /> <include name="lib/**/*.jar" /> </fileset> </path> <!-- ========================================================== --> <!-- Antタスク定義 --> <!-- ========================================================== --> <taskdef classpathref="cobertura.classpath" resource="tasks.properties" /> <!-- ========================================================== --> <!-- Antタスク実行順序 --> <!-- ========================================================== --> <target name="build"> <antcall target="clean" /> <antcall target="instrument" /> <antcall target="create.TEST-war" /> </target> <!-- ========================================================== --> <!-- ディレクトリをクリア --> <!-- ========================================================== --> <target name="clean"> <delete dir="${instrument.class.dir}" /> <delete dir="${cobertura.report}" /> <delete file="${coverage.data}" /> <mkdir dir="${instrument.class.dir}" /> <mkdir dir="${cobertura.report}" /> </target> <!-- ========================================================== --> <!-- カバレッジ測定用コードの埋め込み --> <!-- ========================================================== --> <target name="instrument"> <cobertura-instrument datafile="${coverage.data}" todir="${instrument.class.dir}"> <fileset dir="${class.dir}" excludes="${instrument.class.dir.excludes}" /> </cobertura-instrument> </target> <!-- ========================================================== --> <!-- WARファイル作成 --> <!-- ========================================================== --> <target name="create.TEST-war"> <war destfile="${war.dir}/TEST-${war.name}" webxml="WebContent/WEB-INF/web.xml"> <fileset dir="WebContent"/> <webinf dir="WebContent/WEB-INF"/> <lib dir="${lib.dir}"/> <lib dir="${cobertura.home}" includes="**/*.jar" /> <classes dir="${instrument.class.dir}"/> <classes dir="${src.dir}" includes="${create.war.src.dir.includes}"/> <fileset file="coverageSave.jsp"/> </war> </target> <!-- ========================================================== --> <!-- カバレッジ測定結果を出力 --> <!-- ========================================================== --> <target name="coverageReport"> <!-- アプリケーションサーバ上のカバレッジデータ保存 --> <get src="${coverage.save.url}" dest="result.txt" ignoreerrors="true" /> <!-- カバレッジ測定結果を出力 --> <cobertura-report format="xml" datafile="${coverage.data}" destdir="${cobertura.report}"> <fileset dir="${src.dir}" includes="**/*.java" /> </cobertura-report> </target> </project>
最終的に、「【SampleJob】WEB+DBユニットテスト(Java)①デプロイ」のディレクトリ構成はこんな感じになりました。
WebAndDbUnitSample ├─build ├─src │ ├─dbcp.properties │ └─sample │ └─SampleForm.java ├─testdata │ └─SampleFormTest │ └─init.xls ├─testlib │ ├─dbunit-2.4.7.jar │ ├─junit-4.8.2.jar │ ├─poi-3.2-FINAL-20081019.jar │ ├─poi-contrib-3.2-FINAL-20081019.jar │ ├─poi-scratchpad-3.2-FINAL-20081019.jar │ ├─selenium-java-client-driver.jar │ ├─slf4j-api-1.6.0.jar │ ├─slf4j-ext-1.6.0.jar │ ├─slf4j-migrator-1.6.0.jar │ ├─slf4j-simple-1.6.0.jar │ └─TEST-DbUnitSample.jar ├─testsrc │ ├─WebTester.properties │ ├─iexplore-WebTester.properties │ ├─firefox-WebTester.properties │ └─sample │ ├─HtmlTableAssert.java │ ├─SampleFormTest.java │ └─WebTester.java └─WebContent ├─META-INF ├─WEB-INF │ ├─lib │ │ ├─click-2.2.0.jar │ │ ├─click-extras-2.2.0.jar │ │ ├─commons-dbcp-1.4.jar │ │ ├─commons-dbutils-1.3.jar │ │ ├─commons-lang-2.5.jar │ │ ├─commons-pool-1.5.4.jar │ │ ├─DbUnitSample.jar │ │ └─h2-1.2.135.jar │ ├─click.xml │ └─web.xml └─SampleForm.htm
「【SampleJob】WEB+DBユニットテスト(Java)①デプロイ」のプロジェクト直下には、以下のファイルを置いています。
build.properties
build.xml
coverageSave.jsp
codeAnalysis.properties
codeAnalysis.xml
coverage.properties
coverage.xml
selenium-server.jar
selenium-server-run.bat