表記のとおりです。
動機
Gradle2.6からの機能の一つgradleTestKit
はかなり便利なのですが、まだまだ機能不足で、特に自作プラグインを読み込めないところが弱点であると言ってきました。
Gradle Forumで、質問してもやっぱり、そのあたりの機能はないんだよねーと言われています。
まあ、やり方はわかっていたので、それらを自動でやってくれるようなクラスを作っちゃえばいいんだろうということで、自動で自作プラグインを読み込むクラスを生成するタスクを生やすプラグインを作りました。
Gradle - Plugin: org.mikeneck.gradle-testkit-support-plugin
使い方
プラグインの読み込み
プラグインを読み込みます。なお、Gradle2.6以上(2.5でも動きますが、TestKit自体は2.6からの機能なので2.5以下で使用しても無意味だし、コンパイルエラーになります)、Java8以上でないと動きません。また、configuration.runtime
を利用するので、java
もしくはgroovy
プラグインが必要になります(プラグインを作る場合はいずれかを利用するので問題無いとおもいますが…)。
plugins { id 'groovy' id "org.mikeneck.gradle-testkit-support-plugin" version "0.1" }
テスト依存性の設定
gradleTestKit
に依存しますので、必ずtestCompile
にgradleTestKit()
を指定して下さい。あとSpockを使うと幸せになります。
dependencies { compile 'org.slf4j:slf4j-api:1.7.12' compile 'com.owlike:genson:1.3' compile gradleApi() // gradleTestKitを必ず使うこと testCompile gradleTestKit() testCompile ('org.spockframework:spock-core:1.0-groovy-2.3') { exclude module: 'groovy-all' } }
モデルの指定
モデルを指定します。
model{}
ブロックの中にtestKitSupport{}
ブロックが生えていますので、その中で下記の3つの値を設定してください。
プロパティ | 型 | 設定すべき値 | デフォルト値 |
---|---|---|---|
testSrcDir |
String |
生成されるソースの出力ソースセット | src/test/java |
packageName |
String |
パッケージ名 | 未指定なので必ず指定してください |
className |
String |
生成されるクラスの名前 | TestProject |
コード例
model { testKitSupport { testSrcDir = 'src/test/groovy' packageName = 'com.sample.plugin' className = 'TestProject' } }
コードの生成
モデルが正しく定義されていると、generateTestKitSupport
というタスクが実行可能になりますので、これを実行してください。
$ gradle --daemon gTKS :storeModelForTestKitSupport :generateTestKitSupport BUILD SUCCESS Total time: 5.020 sec $
こんな感じで表示されるでしょう。
これによって、com.sample.plugin.TestProject
というクラスが生成されます。
テストでの使い方
生成されたクラスはExternalResource
クラスを継承したクラスで、内部的にはTemporaryFolder
クラスを利用したクラスになっていますので、JUnitでは@Rule
アノテーションで指定しておくことで機能を利用できます。
JUnitの場合はテストの前後で一時フォルダーが作成され、そこをプロジェクトディレクトリーとして利用することができます。
buildGradle(String)
というメソッドにビルドスクリプトを渡すことで、build.gradle
ファイルが生成されます。このbuild.gradle
では自作プラグインクラスすべてとリソース、および依存ライブラリー(Gradle APIを除く)を読み込みます。- 渡すスクリプトには自作プラグインのプラグインidを読み込むようにしておきます。これでテスト用のプロジェクトに自作プラグインが適用された状態を作り出せます。
run(String...)
というメソッドがありますので、それに実行したいタスク名を渡します。このメソッドから返されるオブジェクトにはbuild()
というメソッドとbuildAndFail()
というメソッドがありますので、成功を期待する場合はbuild()
を、失敗を期待する場合はbuildAndFail()
を呼び出してください。build
およびbuildAndFail
メソッドから返されるオブエジェクトからは標準出力、標準エラー出力、個々のタスクの実行結果などが参照可能です。
サンプルコード(Spock)
class YourPluginSpec extends Specification { @Rule def TestProject testProject = TestProject.target(YourPluginImpl) def setup() { testProject.ready() } def cleanup() { testProject.end() } def 'given build script will success'() { given: def script = """|apply plugin: 'your-plugin-id' |model { | yourPlugin { | definition = 'test' | } |} |""".stripMargin() testProject.buildGradle(script) when: def result = testProject.run('yourTaskName') .build() then: // 標準出力には definition = test が出力される result.standardOutput.contains('definition = test') // タスクは成功する result.task(":yourTaskName").outcome = TaskOutcome.SUCCESS } }
レポジトリー
ここ
TBD
READMEにも書いてありますが、このプラグインが依存しているrule-based-model-generation
プラグインがまだまだ機能が貧弱なため、こちらの改善を進めたいと思っています。