-
Notifications
You must be signed in to change notification settings - Fork 35
Plugin Guide
- Introduction
- Plugin Installation
.feature
Files Location- Step Implementations Location
- Step Implementations
- Before & After Code
- Running Cucumber Features
- Plugin Configuration
- FAQ & Pitfalls
grails-cucumber is a Grails plugin for Cucumber based on Cucumber-JVM. Cucumber-JVM is the JVM implementation of cucumber and it supports many JVM languages. Groovy is one of them.
grails-cucumber is a functional test plugin for grails. It is not meant to implement tests on the unit test level. It is only available in the functional test phase.
The plugin runs cucumber inside a running grails application which allows us to use the grails api in the cucumber step implementations. We can call GORM stuff like dynamic finders, services or even controllers.
grails-cucumber is a normal grails plugin. To use it in your grails application just add it to the plugins
configuration block in BuildConfig.groovy
like this (using the latest availabe version of the plugin):
plugins {
test ":cucumber:0.7.0"
}
The only convention regarding cucumber .feature
files is that they should be in the test/functional
directory. Inside it you can use any layout you like to structure the features.
The plugin will tell Cucumber-JVM to look for features in this directory and Cucumber-JVM will scan it recursivly.
If you need to you can override this path. See Plugin Configuration.
The step implementations follow the same convention as the .feature
s. They should be in test/functional
and inside it you can use any layout you like to structure the steps.
The plugin will tell Cucumber-JVM to look for the steps in this directory and Cucumber-JVM will scan it recursivly.
Note that you should not mix cucumber groovy scripts with other groovy scripts. Cucumber-JVM will run all groovy scripts it will find in the given path. Chances are high that this will fail and is probably not what you want anyway.
If you need to you can override this path. See Plugin Configuration.
This section does contain some basic information for implementing steps: What is possible at all and how do I use specific grails functionality.
There is nothing special about using GORM, just use it as in production code. Having a simple domain class Book
package books
class Book {
String author
String title
}
we can call dynamic finders as usual:
When (~"^I add \"([^\"]*)\"\$") { String bookTitle ->
def book = Book.findByTitle (bookTitle)
...
}
To create a Service in a cucumber step call appCtx.getBean ("<bean name>")
like this:
Given (~"^I have already added \"([^\"]*)\"\$") { String bookTitle ->
def bookService = appCtx.getBean ("bookService")
// do something with your service
}
We can create & use Controllers in the same way as in a normal grails controller integration test. We just have to add some setup & cleanup that we get automatically when we implement normal integration tests by extending GroovyTestCase
. That is, setting up the mock request , response and session objects.
It is just a few lines you have to call from from the cucumber Before
and After
hooks.
since 0. 6.0
Alternatively to adding the two hooks manually we can also add a simple configuration block into a support file (like env.groovy
) which will create the two hooks.
import static grails.plugin.cucumber.Hooks.hooks
hooks {
request ("@req")
}
The integration
setting takes a cucumber tag expression as parameter and adds a Before
& After
hook with the code in the next section passing the tag expression to the hooks.
Here is the required code to put in the Before
and After
hooks to get controller support in the step implementations:
import org.codehaus.groovy.grails.test.support.GrailsTestRequestEnvironmentInterceptor
this.metaClass.mixin (cucumber.runtime.groovy.Hooks)
GrailsTestRequestEnvironmentInterceptor scenarioInterceptor
Before () {
scenarioInterceptor = new GrailsTestRequestEnvironmentInterceptor (appCtx)
scenarioInterceptor.init ()
}
After () {
scenarioInterceptor.destroy ()
}
See Testing-Grails-with-Cucumber-and-Geb for a complete tutorial.
Apart from a single constellation the plugin does/can not provide any support to wrap a scenario into a transaction to automate the cleanup of the database. We will have to provide Before
and After
hooks to setup and cleanup the database (see cucumber & Grails: Transaction Rollback). There are two options:
- re-create the database schema on each scenario
- restore the original database state with update/delete statements
The plugin integrates cucumber as a grails test type into the grails test infrastructure. You can run the cucumber features via the grails test-app
command and the test results will be included in the normal grails test reports.
Currently the plugin registers the cucumber test type only to the functional test phase. To run the cucumber features you call grails by one of the following commands:
grails test-app functional:cucumber
grails test-app :cucumber
Or, if you do not use a second functional test plugin you can also use:
grails test-app functional:
since 0.6.0
If the command line contains :cucumber
, @tag
parameters are evaluated to filter execution of features or scenarios. Standard cucumber syntax applies without the --tags
option keyword. Setting tags on the comand line will overwrite CucumberConfig.groovy
:
grails test-app :cucumber @foo,~@bar @zap
In JUnit we have test suites and tests. In Cucumber we have features, scenarios and steps. The plugin maps features to test suites and scenarios to tests. There is no direct mapping for steps. The steps will be reported as part of their scenario.
Grails does only distinguish between failures and errors and knows nothing about undefined steps. Undefined steps will be therefore reported as failure which makes the scenario fail too.
The plugin integrates into grails test reporting. The normal cucumber output can be found in the html or plain test reports in target/test-reports
.
The plugin does use a couple of default settings that can be overriden by CucumberConfig.groovy
if you need to. If a setting is not given in the configuration file the default will be used.
The defaults in CucumberConfig.groovy
notation are:
cucumber {
tags = []
features = ["test/functional"]
glue = ["test/functional"]
}
The hardcoded test/cucumber
path used in the plugin before version 0.4.0 is now deprecated. If you still like to use it you can add it to the features
and steps
setting in CucumberConfig.groovy
.
cucumber {
features = ["test/cucumber"]
glue = ["test/cucumber"]
}
The plugin will read the configuration from grails-app/conf/CucumberConfig.groovy
. It is a a standard config slurper file.
We can adjust the paths where cucumber will look for
.feature
files and step implementations so putting the configuration along the cucumer files does not work.
Cucumber tags can be set using the tags
configuration option:
cucumber {
tags = ["@implemented", "~@ignored"]
}
tags
is a list of strings where each item corresponds to a single cucumber --tags
option. See the cucumber documentation to read more about the --tags
switch.
To override or extend the locations where cucumber will search for .feature
files you can use the features
option:
cucumber {
features = [
"test/functional/features",
"test/functional/featuresOfCurrentSprint"
]
}
features
is a list of paths where each path is relative (below) the grails application root directory.
Note that settings this option will override the default
test/functional
path. If you want to keep it you have to add it to thefeatures
path list.
To override or extend the locations cucumber will search for groovy scripts with gherkin steps or hooks you can use the glue
option:
cucumber {
glue = [
"test/functional/steps",
"test/functional/hooks"
]
}
glue
is a list of paths where each path is relative (below) the grails application root directory.
Note that settings this option will override the default
test/functional
path. If you want to keep it you have to add it to theglue
path list.
since 0.6.0
The plugin provides a couple of standard hooks that can be enabled using the hooks
configuration block. It should be placed in a groovy file on the glue
path:
import static grails.plugin.cucumber.Hooks.hooks
hooks {
integration ("@i9n")
}
The integration
setting enables grails integration test support which we will get automatically in normal integration tests by extending GroovyTestCase
. It will simply create a Before
and a After
hook pair with the given tag expression to set up and clean up grails integration testing. Note that this is only usefull for ui-less testing.
The following hooks are supported:
-
request
: enable mock request, response and session (see integration testing) -
transaction
: enable automatic rollback (works only in integration test mode, see integration testing) -
integration
: combination ofrequest
andtransaction
(see integration testing)
-
The plugin fails when I try to run features in a non-english language.
If cucumber does not recognize the
# language: <language code>
comment at the beginning of a feature file it is probably because of a byte order marker (BOM). Remove it and try again.