The good news is that we can finally run grails-cucumber using the forked mode introduced in grails 2.3 using the preferred testing style described in Grails: Cucumber with HTTPBuilder & RemoteControl. :-)
It was a long road making grails-cucumber compatible with forked mode. There were a few things that had to be changed in the plugin itself, then there were a couple of issues in grails functional testing setup and finally the remote-control plugin did not work in forked mode because of a reloading issue in spring-loaded.
To summarize, we will need at least the following versions to run the cucumber features with not forked & forked mode:
|not forked||>= 0.11.0-SNAPSHOT||>= 1.4||>= 2.3.8|
|forked||>= 0.11.0-SNAPSHOT||>= 1.5||>= 2.4.0|
the latest version of grails-cucumber is 1.0.0
Now let’s take a look at running the example from Grails: Cucumber with HTTPBuilder & RemoteControl in forked mode.
Running cucumber features in forked mode
What follows is more or less a generic description about running functional tests in forked mode and not specific to (grails-)cucumber.
There are two reasons why we would want to use the forked-mode
- isolation of the the build path from the runtime/test paths
- quicker roundtrips in development because we do not have to wait for jvm/grails startup
On my machine (late 2011, (surprise, sooo old already ;-) it takes about 25 seconds to run
grails test-app functional:cucumberfor the two scenarios in the example in non forked mode. Most of that time is used to startup the jvm and grails.
The first step to use the forked mode is to add the fork configuration into
BuildConfig.groovy. If you created your project with grails 2.3 or above it will already exists.
grails.project.fork = [ // configure settings for the run-app JVM run: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256], // configure settings for the test-app JVM, uses the daemon by default test: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, daemon:true] ]
Next we run
grails test to start the interactive grails console. I’m running the console in the test enviroment so that the remote-control plugin gets enabled in the running grails application (by default it will only be enabled in the test environment).
If you run
ps -ef | grep javain another window you will see two grails java processes running.
We can run our application by simply entering
run-app from the grails console:
grails> run-app | Server running. Browse to http://localhost:8080/Books_remote | Application loaded in interactive mode. Type 'stop-app' to shutdown.
psagain we see four(!) java processes. I expected to see three. Not sure why there are four.
To run the features we can now simply call
test-app functional:cucumber -baseUrl=http://localhost:8080/Books_remote/
.. just taking a few seconds now… since it does not have to start grails anymore.
Note that we have to pass the
baseUrl parameter to
test-app does not know where the application is running (
baseUrl was broken in grails 2.3 until grails 2.3.8).
Make sure you have the slash at the end. In the test code I pass the url to
HttpBuilderand without the slash it will drop the
Books_remotefrom the url path.
and we receive the usual
test-app output from grails and cucumber:
grails> test-app functional:cucumber --stacktrace --verbose -baseUrl=http://localhost:8080/Books_remote/ | Running 2 cucumber tests... 2 Scenarios ( 2 passed ) 6 Steps ( 6 passed ) 0m 0.185s | Completed 2 cucumber tests, 0 failed in 0m 0s | Tests PASSED - view reports in /Users/hauner/Development/Grails/grails-cucumber.git/test/projects/Books_remote/target/test-reports
As in development we can change the application code and the running grails application will reload the changes.
That’s it. Happy forking :)