JUnitタスクを並列実行する方法

Antで複数のJUnitテストを並列に実行する方法です。実行時間の短縮が期待できます。

実装には以下の記事を参考にしました。
solutions daily: Making JUnit tests run parallely

標準の記述

Antで複数のJUnitテストを実行したい場合、普通に書くと以下のようなbuild.xmlになると思います。

<target name="execute.test">
  <junit fork="true" printsummary="true">

    <classpath>
      <path refid="${test.classes}" />
    </classpath>

    <formatter type="xml" />

    <batchtest todir="${test.reports}">
      <fileset dir="${test.sources}">
        <include name="**/*.java"/>
      </fileset>
    </batchtest>
  </junit>
</target>

${test.sources}配下の全テストクラスを実行するターゲットです.
これを複数スレッドで並列に実行できるように書き換えます。

手順

1. ant-contrib(Antの拡張ライブラリ)のjarをダウンロードし、Antのクラスパスに追加します。
2. ant-contribのタスクを有効にするため、以下の内容をbuild.xmlに追加します。

<taskdef
  resource="net/sf/antcontrib/antcontrib.properties"
/>

3. execute.testターゲットを、テストクラスを1つだけ実行するように修正します。

<target name="execute.test">
  <pathconvert property="test.source.relative">
    <fileset file="${test.source.absolute}" />
    <map from="${test.sources}/" to="" />
  </pathconvert>

  <junit fork="true" printsummary="true">

    <classpath>
      <path refid="${test.classes}" />
    </classpath>

    <formatter type="xml" />

    <batchtest todir="${test.reports}">
      <fileset dir="${test.sources}">
        <filename name="${test.source.relative}" />
      </fileset>
    </batchtest>
  </junit>
</target>

4. ant-contribのforeachタスクを使用し、上記3のexecute.testを呼び出します(イメージとしては、foreachタスクがfor文で、そのループの中でexecute.testメソッドを呼び出している、という感じでしょうか)。このforeachタスクのparallel属性をtrueにすることで、それぞれのexecute.testがマルチスレッドで実行されます。また、このときの最大スレッド数をmaxThreads属性で制御できます。

<target name="execute.tests.parallel">
 <foreach
    target="execute.test" 
    maxThreads="5"
    inheritall="true"
    inheritrefs="true"
    parallel="true"
    param="test.source.absolute">
    <path>
      <fileset dir="${test.sources}">
        <include name="**/*.java"/>
      </fileset>
    </path>
  </foreach>
</target>

以上



参考書籍:

Ant 第2版

Ant 第2版