mavenで新しいライフサイクル(integration-test)を定義する

今回はMavenでの新しいライフサイクル(integration-test)の定義方法について。


昨今、テスト用のフレームワークも充実してきてそのフレームワークを用いてやれることも増えてきました。
例えば
 「HTTPリクエストを生成して、実際のWEBアクセスに見せかけて試験する」
 「(テスト実行中のみ)WEB/APサーバを起動して実施する」

といったこともテストケースで簡単に実装出来る環境が整ってきています。
また、アジャイルなプロジェクトも増えてきており、継続ビルド/テスト環境(いわゆるCI環境)を構築することも多いのではないでしょうか。
ただこの「結合試験テストケース × アジャイル(CI環境)」で困るケースがあります。

例えばCI環境としてSVNCVSを監視し、コミット毎に「ビルド ⇒テスト」を実行する」という環境を構築した場合、もちろんビルドにもテストにもあまり時間をかけたくありません。(せめて1〜2分で終わるくらい?)
しかしテストフレームワークを使用した結合試験では先述したように
 「HTTPリクエストを生成して、実際のWEBアクセスに見せかけて試験する」
 「(テスト実行中のみ)WEB/APサーバを起動して実施する」

といったことをやっていますので、テスト実施時間も長くなりがちです。
この場合、最悪なケースは重大なコミット時にテスト実施中であるためにそれを見逃し、深刻なデグレを引き起こしてしまうといったことが考えられます。
人間は弱いモノで、
 「CI環境があればデグレはない」
と考えがちですので、これはなかなか発見されないでしょう。
ひょっとしたら発見されることなくリリースされてしまうかもしれません。

この場合の解決策として一番まっとうなものは
 「単体試験は常時(コミットの度)実施し、結合試験は日時(04:00)実施する」
といったものであると考えます。
(XPのベストプラクティスにも結合テストは「最低1日1回」ってありますし)
で、これを実現するmavenの仕組みとして新しいライフサイクル(integration-test)を作成しよう、ということになるのです。

新ライフサイクル(integration-test)の要件としては
 (1) ライフサイクル「test」 時にはテストが実施されない
 (2) ライフサイクル「integration-test」 時にはテストが実施される

というものになります。

具体的には「maven-surefire-plugin」を使用し、の合わせ技で定義できます。
方法としてはを使用する方式とを使用する方式の2パターンあります。


◆方法(1)(を使用する方法)

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
            <skip>true</skip>
        </configuration>
        <executions>
            <execution>
                <id>surefire-integration-test</id>  
                <phase>integration-test</phase>
                <goals>
                    <goal>test</goal>
                </goals>
                <configuration>
                    <skip>false</skip>
                </configuration>
            </execution>
        </executions>
    </plugin>

    ・・・

<plugins>


◆方法(2)(を使用する方法)

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
            <excludes>
                <exclude>**/*Test.java</exclude>
            </excludes>
        </configuration>
        <executions>
            <execution>
                <id>surefire-integration-test</id>  
                <phase>integration-test</phase>
                <goals>
                    <goal>test</goal>
                </goals>
                <configuration>
                    <excludes>
                        <exclude>none</exclude>
                    </excludes>
                </configuration>
            </execution>
        </executions>
    </plugin>

    ・・・

<plugins>

この2つの使い分けとしては

 (1)の方式
  ⇒「結合試験用のプロジェクトが分離されており、結合試験実施時はプロジェクト内全てのテストケースが対象となる」

 (2)の方式
  ⇒「単体試験/結合試験のプロジェクトが統一されており、結合試験実施時は特定のテストケースが対象となる」

といった感じになると思います。
その他注意点としては「」についてで、「plugin->configration ⇔ execution->configration」 には親子関係があることです。
そのため、「execution->configration」 にてまたはの設定を上書きしてやらないと正しく動作しません。


今回の記事を書くにあたり、以下を参考にさせて頂きました。

◆参考
http://maven.apache.org/plugins/maven-surefire-plugin/
http://docs.codehaus.org/display/MAVENUSER/Maven+and+Integration+Testing
http://shin1o.blogspot.com/2009/03/mavenwebintegration-test.html