There’s a fairly popular technique in Grails plugin development where the plugin has test apps stored in
test/projects/*, each of which references the plugin by including
grails.plugin.location."my-plugin" = "../../.." in its BuildConfig.groovy. Doing this allows you as a plugin developer to:
Automate tests for sample projects using the plugin with significantly different configurations.
Test using domain classes, controllers, etc. that shouldn’t be packaged with the plugin.
Test drive, changing code in both the test app and the plugin without the need to use
grails install-pluginto pick up changes.
The downside is that to run all the plugin project’s tests it’s necessary to run the plugin’s own tests, then change directory into each of the test apps and run their tests. Continuous integration config is also fiddlier for the same reason.
I wanted to find a way to automate this so I could run all my plugins' tests with a single command. I could write a bash script or an Ant build I guess, or even use maven <shudder>. However keeping things in Groovy-land I decided to try using Gradle which I’ve been meaning to look into for a while now. I saw Hans Dockter’s presentation on Gradle at the London Groovy & Grails Exchange back in December and was impressed with how terse and expressive the syntax is, especially compared to XML based formats. Unfortunately one thing Gradle doesn’t grok yet is Grails.
The solution I’ve come up with is based on email@example.com/msg01871.html">a post by Helmut Denk on the gradle-user list. Gradle just uses Ant’s exec task to shell out and execute the appropriate Grails command. Combining this with Gradle’s multi-project build support I now have plugin builds that can be run with
gradle test that will automatically descend into the test apps under test/projects/*.
The build.gradle file at the root of the project defines clean and test tasks: The test task will run the plugin’s unit tests. The clean task is defined just once for all projects as there’s no difference in how it is done - a nice examply of Gradle’s DRY-ness.
Then in settings.gradle I tell Gradle where to find the various sub-projects: Finally each test app has it’s own build.gradle that defines its test task: This is only necessary if the test apps run tests differently to the plugin - here my app is running integration rather than unit tests - otherwise I could have defined test in the same DRY manner as clean.
The process is not as fast as it could be if Grails were wired in to Gradle properly.
gradle clean test for the Springcache plugin and its two test apps takes just over 2 minutes on my MBP. Also, my Gradle-fu leaves a lot to be desired right now so I’m sure there are improvements that could be made with the way I’m handling the sub-projects. But, for the purposes of a pre-commit test run or Hudson build this works pretty well.