afnf.net

ブログエンジン(5) Maven+JaCoCoでカバレッジ計測

続けるって難しい。2月は2本しか書いてないしな。

えっと、前回のエントリでは、Maven+Jetty+Seleniumで総合テストを行うための構成を簡単に紹介しました。今回は、JaCoCoでカバレッジ計測を行い、テストレポートを出力するところまでを紹介します。

※Spring Boot+Maven+Selenium+JaCoCoも可能です。詳細はこちらのエントリで。

JaCoCoについて

JaCoCoはEMMAの後継となるコードカバレッジツールです。なんやかんやで良い感じらしいです。

Java Agentによってコードカバレッジの測定が行われますので、JVMオプションの設定が必要になります。ここポイント。試験に出ます。

単体テストとJaCoCo

test-compileフェーズでjacoco:prepare-agentを実行すると、jacocoArgsにJVM用のオプションが設定されます。 これをmaven-surefire-pluginのargLineに渡せばOKです。デフォルトでJUnitのJVMがフォークされるので、テスト終了と同時に、target/jacoco.execへ計測結果が出力されます。

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.6.5.201403032054</version>
  <executions>
    <execution>
      <id>prepare-agent</id>
      <phase>test-compile</phase>
      <goals>
        <goal>prepare-agent</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <includes>
      <include>net/afnf/blog/**</include>
    </includes>
    <excludes>
      <exclude>net/afnf/blog/domain/**</exclude>
      <exclude>net/afnf/blog/mapper/**</exclude>
    </excludes>
    <propertyName>jacocoArgs</propertyName>
    <append>true</append>
  </configuration>
</plugin>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.16</version>
  <configuration>
    <argLine>${jacocoArgs}</argLine>
  </configuration>
</plugin>

propertyNameやargLineはデフォルト設定でOKなので、実際には未設定でもかまいません。

統合テストとJaCoCo

前回は、jetty:startを使って統合テストのJettyを起動する方法を紹介しましたが、この場合、MavenのJVMから直接起動されてしまいます。このため、以下のようにMAVEN_OPTS環境変数でJava Agentの設定を行う必要があります。

export MAVEN_OPTS=-javaagent:/home/xxxxxx/.m2/repository/org/jacoco/org.jacoco.agent/0.6.5-SNAPSHOT/org.jacoco.agent-0.6.5-SNAPSHOT-runtime.jar=destfile=/home/xxxxxx/blog-java1/target/jacoco.exec,includes=net/afnf/blog/**,excludes=net/afnf/blog/domain/**:net/afnf/blog/mapper/**,append=true

前述のjacocoArgsは使えません。メンテナンス性が最悪。

さらに、MavenのJVMが終了してようやくtarget/jacoco.execが書き出されるため、テストとレポート生成のMaven実行を分けなければなりません。面倒です。

mvn -Pstaging-test clean verify
mvn jacoco:report

じゃあどうするか。

統合テスト用のJettyを、別のJVMで起動させればよいのです。ということで、jetty:startではなく、jetty:run-forkedを使います。

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <version>9.1.0.v20131115</version>
  <executions>
    <execution>
      <id>run-forked-jetty</id>
      <phase>pre-integration-test</phase>
      <goals>
        <goal>stop</goal>
        <goal>run-forked</goal>
      </goals>
      <configuration>
        <contextPath>/${pom.contextPath}</contextPath>
        <jvmArgs>-Djetty.port=${selenium.jettyport} ${jacocoArgs}</jvmArgs>
        <waitForChild>false</waitForChild>
        <reload>manual</reload>
        <scanIntervalSeconds>0</scanIntervalSeconds>
        <daemon>true</daemon>
      </configuration>
    </execution>
    <execution>
      <id>stop-jetty</id>
      <phase>post-integration-test</phase>
      <goals>
        <goal>stop</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <systemPropertiesFile>src/filters/${pom.confdir}/config.properties</systemPropertiesFile>
    <reload>automatic</reload>
    <scanIntervalSeconds>1</scanIntervalSeconds>
    <webApp>
      <contextPath>/${pom.contextPath}</contextPath>
    </webApp>
    <stopKey>key1</stopKey>
    <stopPort>9999</stopPort>
    <stopWait>10</stopWait>
  </configuration>
</plugin>

デフォルトだと、Jettyが終了するまで制御が返りません。waitForChild=falseとすることでJetty起動後に制御が戻り、integration-testフェーズが実行されます。

jvmArgsがキモです。jacocoArgsを設定することで、カバレッジの計測が可能になります。

統合テスト終了後、post-integration-testのjetty:stopによりフォークしたJVMが終了し、jacoco.execが書き出されます。append=trueとしたので上書きにならず、JUnitの計測結果に追記されます。

reload、scanIntervalSeconds、daemonは無くてもOKです。なんとなく設定しました。

ちなみにwaitForChildですが、古いドキュメントには記載があるのですが、新しいドキュメントにはありません。実は非推奨だったりするのでしょうか。

2014/11/23追記:waitForChildの説明が追加されていました。
http://www.eclipse.org/jetty/documentation/current/jetty-maven-plugin.html

テストレポート生成

これは簡単で、jacoco:reportを実行するだけです。target/jacoco.execからHTML形式のレポートが生成されます。indexはtarget/site/jacoco/index.htmlです。

生成結果はこんな感じです。参考までにzip置いときます

20140316_jacoco_report

commonパッケージのカバレッジが低いのは、SMTP関連のテストをサボっているからです。

まとめ

そんなこんなで、一発で単体テスト+統合テスト+レポート生成まで行けるようになりました。

mvn -Pstaging-test clean verify jacoco:report

いい感じ。

続き

ブログエンジン(6) asset minify on-demand

comments (0)

blog-java2 engine (build:2017-09-13 21:46 JST)