Webのユニットテスト⑥ Java

前回の続きです。
[コンパイル→WAR作成→アプリケーションサーバにデプロイ]を行うHudsonジョブを作ります。


プロジェクトのディレクトリ構成はこんな感じになっています。

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
│ ├─selenium-server.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
│  └─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

新規ジョブを作成

以前に作ったジョブをコピーして作ります。



ジョブの設定を変更

基本的にコピーした設定をそのまま使います。
SVNレポジトリURLやプロジェクトのルートフォルダ名は変更する必要があります。


このジョブではユニットテストを実行しないので、「JUnitテスト結果の集計」チェックは外しておきます。


「Deploy to container Plugin」を使ってアプリケーションサーバへのデプロイを行います。
プラグインのインストールはいつもと同じで、設定はこんな感じです。




build.xmlなどを置く

以前に作ったbuild.xml等をプロジェクト直下に置きます。


 build.properties
 build.xml
 codeAnalysis.properties
 codeAnalysis.xml
 coverage.properties
 coverage.xml


以下のファイルは、Webアプリケーション用に変更しています。


■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
# テスト結果ファイル格納ディレクトリ
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


build.xml

<?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="unitTest" />
  </target>
  <target name="build-unitTest-coverage">
    <antcall target="unitTest" />
    <ant antfile="coverage.xml" target="coverageReport" inheritAll="true" inheritRefs="true" />
  </target>

  <!-- ========================================================== -->
  <!-- ディレクトリをクリア -->
  <!-- ========================================================== -->
  <target name="clean">
    <delete dir="${class.dir}" />
    <delete dir="${report.dir}" />
    <delete dir="${war.dir}" />
    <mkdir dir="${class.dir}" />
    <mkdir dir="${report.dir}" />
    <mkdir dir="${war.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>
  </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="unitTest">
    <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>
  </target>

</project>


■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*


■coverage.xml

<?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 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}"/>
    </war>
  </target>

  <!-- ========================================================== -->
  <!-- カバレッジ測定結果を出力 -->
  <!-- ========================================================== -->
  <target name="coverageReport">
    <cobertura-report format="xml" destdir="${cobertura.report}">
      <fileset dir="${src.dir}" includes="**/*.java" />
    </cobertura-report>
  </target>
  
</project>

Hudsonから実行してみる

実行方法は今までどおりです。



Tomcatの管理画面(http://localhost:8080/admin/html)を覗いてみると、
WebAndDbUnitSample.warとTEST-WebAndDbUnitSample.war(カバレッジ測定用)がデプロイされているのが確認できます。