Hudsonの使い方⑲ Hudsonでユニットテスト網羅率測定(Java)

Cobertura Pluginをインストールして、
ユニットテストの網羅率(カバレッジ)測定をしてみます。


網羅率を確認すれば、
ユニットテストを実行していない箇所が一目でわかります。

Slave端末にCoberturaをインストールします。

Coberturaをダウンロードして、適当なフォルダに展開します。
COBERTURA_HOME/lib/をANT_HOME/libにコピーします。

CoberturaをAntから実行できるようにbuild.xmlを追加します。

管理しやすいように、以前に作ったbuild.xmlと分けて作りました。


■coverage.properties

###################################################
# カバレッジ作成定義
###################################################
# Coberturaインストールディレクトリ
cobertura.home=C:/Cobertura1.9.4.1
# カバレッジデータファイル
coverage.data=cobertura.ser
# クラスファイル格納ディレクトリ(カバレッジ測定用)
instrument.class.dir=instrument
# カバレッジ測定結果出力ディレクトリ
cobertura.report=coverageReport
# カバレッジ測定対象外のクラス
instrument.class.dir.excludes=**/*Test.class, **/TestBase.class


■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.dir}/**/*.jar" />
    </fileset>
  </path>

  <!-- ========================================================== -->
  <!-- Antタスク定義 -->
  <!-- ========================================================== -->
  <taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
  
  <!-- ========================================================== -->
  <!-- Antタスク実行順序 -->
  <!-- ========================================================== -->
  <target name="coverage">
    <antcall target="clean" />
    <antcall target="instrument" />
    <antcall target="unitTest">
      <reference refid="build.classpath" torefid="build.classpath"/>
    </antcall>
    <antcall target="coverageReport" />
  </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>
  
  <!-- ========================================================== -->
  <!-- ユニットテスト実行 -->
  <!-- ========================================================== -->
  <target name="unitTest">
    <junit fork="yes" maxmemory="512m" printsummary="on">
      <classpath refid="cobertura.classpath" />
      <classpath location="${instrument.class.dir}" />
      <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>

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

build.xmlを変更します。

Antタスク実行順序でカバレッジ有り/無しを指定して、
ユニットテストを実行できるようにしておきます。


ビルドに必要なクラス参照パスの定義はbuild.xmlの一箇所にしておきたいので、

build.xmlからcoverage.xmlに渡します。


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}" />
    <pathelement path="${stub.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.jar" />
  </target>
  <target name="build-unitTest">
    <antcall target="build" />
    <antcall target="unitTest" />
  </target>
  <target name="build-unitTest-coverage">
    <antcall target="build" />
    <ant antfile="coverage.xml" target="coverage">
      <reference refid="build.classpath" torefid="build.classpath"/>
    </ant>
  </target>

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

  <!-- ========================================================== -->
  <!-- JARファイル作成 -->
  <!-- ========================================================== -->
  <target name="create.jar">
    <jar destfile="${jar.dir}/${jar.name}">
      <fileset dir="${src.dir}" includes="${create.jar.src.dir.includes}"/>
      <fileset dir="${class.dir}" excludes="${create.TEST-jar.class.dir.includes}"/>
    </jar>
    <jar destfile="${jar.dir}/TEST-${jar.name}">
      <fileset dir="${class.dir}" includes="${create.TEST-jar.class.dir.includes}"/>
    </jar>
  </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>

プロジェクトの設定でAntの呼び出しを変更します。(赤枠の部分です)

targetをbuild-unitTestからbuild-unitTest-coverageに変更します。

Cobertura Pluginをインストールします。

ジョブの設定でCoberturaカバレッジ・レポートをチェック

Coberturaの出力結果ファイルを指定します。(赤枠の部分です)

ジョブを実行します。

カバレッジが表示されます。(赤枠の部分です)


プロジェクト/パッケージ毎のカバレッジが表示されます。


ファイル/クラス毎のカバレッジが表示されます。
ソース内でのユニットテスト実行と非実行の行がハイライト表示されます。


おっと、ソースコメントが文字化けしてますね・・・
ソースはUTF-8なんですが、Cobertura Pluginは、
エンコーディングを指定できないみたいだ・・・(;´Д`)


とりあえず保留ヽ(`Д´)ノ