m-namikiの日記

おもしろき こともなき世を おもしろく

Groovyによる宣言的セットアップ

Groovyによる宣言的セットアップ

jUnit実践入門の第7章「テストフィクスチャ」で、フィクスチャ(テストデータ)のセットアップ方法が紹介されています。フィクスチャのセットアップにはインラインセットアップや暗黙的セットアップ、外部リソースからのセットアップなど色々な方法がありますが、個人的にGroovyによる宣言的セットアップというのが気になったので実際にやってみました。

Groovyプラグインのインストール

Groovy用のEclipseプラグインがあるので、まずはそれをインストールします。
Help->Install New Software...を選ぶとウィンドウが表示されるのでAddボタンをクリックして以下の内容を入力します。

Name Location
Groovy Eclipse Plugin http://dist.springsource.org/release/GRECLIPSE/e4.3/

インストールが終わっていつも通り再起動すると、コンテキストメニューのNewにGroovy関連が追加されます。試しにGroovy Classを作ってみるとJava Classと同様のウィザードが表示されるので、クラス名を「Hello」にしてFinishボタンをクリックするとHello.groovyが作成されます。

で、ここで一つ問題が。Groovyの書き方が分からない…w まぁそれは今回の主目的からは外れるので取り敢えず置いておくことにします。

セットアップを書いてみる

ユーザー情報を操作するDaoクラスのテストのセットアップをGroovyで書く、という仮想シナリオです。
まずはユーザー情報から。

public class User {
    private String userId;
    private String password;
    private String email;
    private Date birthDay;
    private Integer gender;

    /*
     * getter/setter省略。
     */
}

次にこのユーザー情報を生成するセットアップ。これはGroovyです。

class UserDaoTestHelper {
    static User createUser_通常ユーザーの場合() {
        new User(
                userId: "m-namiki",
                password: "pass",
                email: "example@sample.com",
                birthDay: new Date("2014/01/01 00:00:00"),
                gender: 0
                )
    }
}

で、最後にこれを使ったテストコードです。

public class UserDaoTest {

    @Test
    public void test() {
        User user = UserDaoTestHelper.createUser_通常ユーザーの場合();

        assertThat(user.getUserId(), is("m-namiki"));
        assertThat(user.getPassword(), is("pass"));
        assertThat(user.getEmail(), is("example@sample.com"));
        assertThat(user.getBirthDay(),
                is(new DateTime(2014, 1, 1, 0, 0, 0).toDate()));
        assertThat(user.getGender(), is(0));
    }

}

セットアップの部分でどんなデータなのかを分かりやすく書けるので、なかなか使い勝手は良さそうです。ただGroovy側で色々頑張ろうとするとそれは本末転倒なことになってしまうのでそこら辺の線引きをきちんと決めておかないと混乱の元になりそうなので注意しないとダメですね。

自分がテストを書く場合だと最近はインラインセットアップが多いですが、以前SAStrutsを使ったときにDBに対するテストを行う際はExcelでデータを作成する、というやり方がチームの人にかなり好意的に受け入れられていましたし、自分でも分かりやすく感じました。ただこれもデータを参照するのに外部ファイルをイチイチ開かなきゃいけないのがちょっと手間で、できればテストコードから簡単に、かつ見易い状態で参照できるのが良いはずなので、Groovyによるセットアップをプロジェクトに導入してみて色々試していきたいと思います。

実際にやってみた

上記はだいぶ前に書いたのですが(3ヶ月前…)ずっと下書きに入っててアップするのを忘れてました。なので、現在担当しているプロジェクトで導入してみた顛末も追記しておきます。

フィクスチャ自体は上記の通りHelperクラスを作ってそこで作成するようにした結果、だいぶコード量が少なくなってテストコードも見通しがよくなりました。
ただMavenでビルドする際にプラグインの追加等をしておかないと、*.groovyがコンパイルされず、当然それを利用しているクラスもコンパイルエラーとなるので、pom.xmlの設定をメモしておきます。

まずはdependenciesに以下を追加。

<dependency>
    <groupId>org.codehaus.groovy</groupId>
    <artifactId>groovy-all</artifactId>
    <version>1.8.9</version>
</dependency>

次にpluginsに以下を追加。

<plugin>
    <groupId>org.codehaus.gmaven</groupId>
    <artifactId>gmaven-plugin</artifactId>
    <version>1.4</version>
    <configuration>
        <providerSelection>1.8</providerSelection>
        <sourceEncoding>UTF-8</sourceEncoding>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>generateTestStubs</goal>
                <goal>testCompile</goal>
            </goals>
            <configuration>
                <sources>
                    <fileset>
                        <directory>${pom.basedir}/src/test/java</directory>
                        <includes>
                            <include>**/*.groovy</include>
                        </includes>
                    </fileset>
                </sources>
            </configuration>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>1.8.9</version>
        </dependency>
    </dependencies>
</plugin>

これで、例えば mvn test 等を実行した際にGroovyが使えるようになります。

日本語文字化け問題

上記のplugin -> configuration -> sourceEncoding で文字コードを指定していますが、実はこれは効きません。gmavenのJIRAを見ても解決済みとなっていますが、実行すると.groovyに日本語が含まれている場合はコンパイルエラーとなってしまいます。

回避策としては、Windowsの場合、以下のように環境変数を設定してやると上手くいきますが、なんとも釈然としないですね...。

set MAVEN_OPTS="-Dgroovy.source.encoding=UTF-8"

参考にさせて頂いたページ