spockを既存のJavaプロジェクトに導入するための設定方法


会社の先輩にspockというテスティングフレームワークがいいよ!と教えて頂きました。どうやらParameterizedTestが非常にやりやすかったり、テスト失敗時のエラーメッセージが分かりやすかったり色々嬉しいそうです。

じゃあ使ってみよう!ということで既存のJavaプロジェクトに導入する想定で設定してみました。

ちなみにIntellijを使いますが、特に追加で必要なものはありません。Eclipseの人はGroovy用のpluginが必要ですので、この辺りを参考にしてみてください。

前提知識

spockはJava、Groovyのためのテスティングフレームワークです。JUnitやTestNGと同じようなものです。

spockはGroovyで書きます。Groovyは.groovyという拡張子のファイルに処理を記述します。

spockはGroovyのコードとして書く訳ですが、実行環境さえ整えればJavaプロジェクトと共存できます。

テスト対象のコード

プロジェクトフォルダのsrc/main/java/com/tsukaby/spock/sampleに以下のファイルがあるとします。

package com.tsukaby.spock.sample;

public class Greeter {
  public static String greet(String name) {
    return "Hello " + name;
  }
}

今回はこれをテストして行きます。想定した通りにgreetしてくれるかを検証します。

依存ライブラリ設定

pom.xmlに以下を追記します。

    <dependency>
      <groupId>org.spockframework</groupId>
      <artifactId>spock-core</artifactId>
      <version>0.7-groovy-2.0</version>
      <scope>test</scope>
    </dependency>

初めはgroovy-allも必要かと思っていたのですが、どうやらspock-coreに入っているようです。他にもエラーが出たのでorg.apache.ivyを追加してみたりもしましたが、どうやら不要なようでした。spock-core1つだけで良いというのはお手軽感ありますね!

テストコード追加

上記のdependencyを加えると右クリック -> New -> Groovy Classを選択できるようになりますので選択します。

プロジェクトフォルダのsrc/test/java/com/tsukaby/spock/sample以下にGreeterTest.groovyを作成します。(※src/test/javaに置いていますが、src/test/groovyなどにしても良いかもしれません)

package com.tsukaby.spock.sample

import spock.lang.Specification

@GrabConfig(systemClassLoader = true)

class GreeterTest extends Specification {
    def "名前付きで返事をしてくれること"() {
        expect:
        Greeter.greet(name) == message
        where:
        name   | message
        "Taro" | "Hello Taro"
        "Jiro" | "Hello Jiro"
    }
}

この状態でRunを押すとJUnit設定で実行されますが、無事起動できました。

一応エラーも確認してみます。

null | “Hello “の行を追加して実行してみます。

package com.tsukaby.spock.sample

import spock.lang.Specification

@GrabConfig(systemClassLoader = true)

class GreeterTest extends Specification {
    def "名前付きで返事をしてくれること"() {
        expect:
        Greeter.greet(name) == message
        where:
        name   | message
        "Taro" | "Hello Taro"
        "Jiro" | "Hello Jiro"
        null   | "Hello "
    }
}

結果は以下です。

Condition not satisfied:

Greeter.greet(name) == message
        |     |     |  |
        |     null  |  Hello 
        Hello null  false
                    4 differences (60% similarity)
                    Hello (null)
                    Hello (----)
 <Click to see difference>

    at com.tsukaby.spock.sample.GreeterTest.名前付きで返事をしてくれること(GreeterTest.groovy:10)

nameが「null」でmessageが「Hello 」のときgreetの結果が「Hello null」なので、結果==はfalseになっています。※Javaだと文字列 + nullは”null”という文字が連結されるためです。

60% similarityとか出てるあたりも凄いですね・・・

という訳で、基本的にdependency追加するだけで普通に使えました。後は通常のクラスではなくて、Groovyクラスを作成するところに気をつけていれば簡単に導入できそうです。

まだまだDBテストやモック注入や他フレームワークとの連携など未知な部分はありますが、とりあえず今回はここまでです。