GeekFactory

int128.hatenablog.com

TestKitによるGradleプロジェクトのテスト

最近のGradleで導入されているTestKitを使ってみたのでメモします。

TestKitでできること

TestKitを利用すると、Gradleプロジェクトに対するテストを実行できます。例えば、何かの設定ファイルを自動生成するタスクをGradleで定義している場合に、そのタスクに対するテストコードを記述できます。TestKitはSpockと併用できるので、BDDスタイルでテストコードを書くこともできます。

この仕組みを応用すると、Gradleプラグインを適用したプロジェクトに対するテストを実行できます。Gradleプラグインの受け入れテストとも言えますね。詳細は The Gradle TestKit - Gradle User Guide Version 2.14 を参照してください。

使い方

ここでは、テスト対象のプロジェクトがGradle 2.13と1.12の両方でちゃんと動作するかテストする例を考えます。

  • build.gradle - テストを実行するプロジェクト
  • src/test/groovy/ExampleSpec.groovy - テストコード
  • fixture/build.gradle - テスト対象のプロジェクト

まず、テスト対象のプロジェクトを作ります。単にGradleバージョンを表示する雑なビルドスクリプトにしておきます。

// fixture/build.gradle
task show << { println gradle.gradleVersion }

それから、TestKitを利用してテストを実行するプロジェクトを作ります。

// build.gradle
plugins {
    id 'groovy'
    id 'java-gradle-plugin'
}

repositories {
    jcenter()
}

dependencies {
    testCompile('org.spockframework:spock-core:1.0-groovy-2.4') {
        exclude module: 'groovy-all'
    }
}
// src/test/groovy/ExampleSpec.groovy
import org.gradle.testkit.runner.GradleRunner
import spock.lang.Specification
import spock.lang.Unroll

class ExampleSpec extends Specification {

    @Unroll
    def "test should be success on Gradle #version"() {
        when:
        GradleRunner.create()
                .withProjectDir(new File('fixture'))
                .withArguments('show')
                .withGradleVersion(version)
                .forwardOutput()
                .build()

        then:
        noExceptionThrown()

        where:
        version << ['2.13', '1.12']
    }

}

テストを実行してみます。

./gradlew check

テストレポートを確認すると、テストケースが2つ実行されて、それぞれ2.13と1.12が表示されていることがわかると思います。

Gradle SSH Pluginへの適用

Gradle SSH PluginはGradle 1系も動作対象に含めているため、受け入れテストを2.13と1.12で実施しています。これまではGradle Wrapperのプロパティファイルを無理やり書き換えて複数のバージョンでテストを実行しましたが、TestKitを利用することで独立した環境でテストを実行できるようになりました。

以下の流れでビルドを実行しています。

  • プラグインプロジェクトをビルドする(test
  • プラグインプロジェクトの成果物をMaven Localにリリースする(publishToMavenLocal
  • 受け入れテストプロジェクトではMaven Localに存在するプラグインを適用する(buildScriptrepositoriesmavenLocal()を指定し、apply pluginを実行)
  • 受け入れテストプロジェクトを実行する

プラグインの受け渡しはGradle 2.8以降であれば withPluginClasspath() が使えるのですが、今回はGradle 1系でテストする必要があるのでMaven Localを採用しました。

TestKitはプラグイン開発者には便利かもですね。