Grails Tests with Cucumber
Recently one of my customers decided to introduce functional tests. The tests should be run beside the already existing unit and integration tests, utilizing a behaviour-driven development approach (BDD). Behaviour-driven development is an approach to specification based testing, instead of source code based testing. Cucumber enables writing BDD specifications for the Ruby programming language, but there are various implementations for other environments. One of them is Cucumber-JVM, a port of Cucumber for the Java virtual machine.
Cucumber components can be devided into three categories: features, steps and hooks.
Features contain the human-readable specification. A specification consists of a description and various scenarios that need to be successfully executed. A scenario has at least three parts:
- Given a textual description that describes the assumption under which the specification must hold
- When a textual description of the action that causes some behaviour
- Then a textual description of the consequence that was caused by the action
Of course, the term “textual description” is not quite true as there needs to be some sort of common agreement about the syntax/semantic of feature files. For writing feature files, Cucumber uses Gherkin, a small programming language with a convenient to read syntax. Let’s have an example:
The example feature description above shows the definition of a single section. Gherkin would allow multiple scenarios and slightly complex scenario definitions with multiple given/when/then blocks. As can be seen above, the feature is human-readable and definitly not as complex as actual source code.
In my case, the customers application is a Grails application. There is a Cucumber Grails plugin available that we chose to add to our
BuildConfig.groovy as additional plugin dependency.
Be aware that Groovy 2.1.x ships with Groovy 1.8.x. The current Cucumber Grails plugin (0.10.0) has a dependency on the Spock Groovy 2.0 build that needs to be excluded manually in
BuildConfig.groovyin case you’re running Grails <= 2.1.x.
Once the Grails plugin is added to
BuildConfig.groovy, Cucumber specifications can be executed by running
test-app. Let’s assume we saved the specification above in a file called
AdminLogin.feature. In order to let the Cucumber plugin find the feature specification in the classpath, it needs to be put in the
test/functional folder. Afterwards we can tell Grails to run all functional Cucumber tests with the following command:
Be aware that this restricts
test-app to execute only functional Cucumber tests. All functional tests can be executed without the selector via
The result of running
test-app looks similar to this:
You can implement missing steps with the snippets below:
Ups, we wrote a specification but there is an important piece missing: the so-called steps and hooks. Steps are needed to programmatically interact with our application. Cucumber leaves the decision about the tool we use for the steps up to us. As the project is about a web application, we needed some sort of web testing library to implement the steps. We chose to go with Geb, a Groovy library to automate web testing.
The Grails plugin output shown above already gives us a hint on how the step implementations should look like. We can copy these step definition stubs as a basis for our step implementation. The steps are defined in a simple Groovy file, it’s recommended to use a separate package to avoid loading issues by the Cucumber Grails plugin. The file is placed in the
test/functional/steps folder (because we are using the
steps package in the Groovy file) of the application:
Then are actually static method calls to the Cucumber-JVM Groovy API. Every method is called with two arguments: a regular expression pattern (the bitwise negator is used to generate a
java.util.regex.Pattern from the
String) and a closure. The closure code comes with as many parameters as the regular expression amount of groups. Because we used double quotes for the link in the feature file we triggered Cucumber to guess this was a valid argument to our closure block. Of course the regular expression can be customized if needed, Cucumber only provides a starting point with the given stub code.
Now it’s time for Geb entering the stage. In order to add a Geb
Browser instance to our step code, we need to add a hook to our code. Cucumber hooks are needed to execute code before and after the execution of a scenario. In our case we want the code to be global, as we use Geb in every function Cucumber test case and need to ensure it is setup correctly. We place the Groovy file containing the hooks in the
test/functional/support folder, as the Groovy code is using the
BindingUpdater ensures that every step has access to the
Browser instance via a
browser variable. In addition, it provides a set of methods that are automatically forwarded to this
Browser instance. Examples include,
via and other important methods of the Browser. Let’s see how our steps can finally be implemented by utilizing Geb:
As you can see, instead of writing
browser.go link we can simply use
go link because the
BindingUpdater set up method forwarding for this method. After the given link is opened with
go link a Geb page is used to validate whether the login page is now shown in front of the secured page:
Geb uses the
at verifier to determine whether the login page is shown or not.
We’re done with our first Cucumber specification!
I created a blank Grails 2.1.5 project and added the example above including an initial Geb and Cucumber configuration that should help getting things up and running.
The Grails Cucumber plugin adds Cucumber-JVM support to Grails applications. Together with Geb, Cucumber can be used to create BDD-style specifications that in turn are executed at run-time using the Groovy web testing library underneath.