Filed under: Cucumber, Gradle, Programming, — Tags: Cucumber-JVM, JUnit, Java — Thomas Sundberg — 2015-12-26
Gradle is a great build tool. Cucumber-JVM is a great tool for executing Gherkin. They don't really work well together. At least not out of the box. Gradle defaults to hide the output on stdout and stderr. This is very unfortunate since this means that the code snippets Cucumber-JVM suggests when there is a missing step are hidden.
Let me show you an example on how to setup a Gradle project so it can execute Cucumber-JVM and give you the snippets you want as starting points for your steps.
I assume that you have Gradle installed. If not, now is a good time to install it.
With Gradle installed, all we need is a project to work with. The easiest way to get started is to clone the getting started project available on GitHub.
I cloned it using: git clone git@github.com:cucumber/cucumber-java-skeleton.git
With a cloned project, it is time to get started with the task of executing it using Gradle.
The first step is to create a file called build.gradle
in the root of the project.
Then add the content below to it.
build.gradle
apply plugin: 'java' dependencies { testCompile 'info.cukes:cucumber-java:1.2.4' testCompile 'info.cukes:cucumber-junit:1.2.4' testCompile 'junit:junit:4.12' } repositories { mavenCentral() } test { testLogging.showStandardStreams = true systemProperties System.getProperties() }
This Gradle project will be used to build a Java project. This means that we have to apply the Java plugin.
We also need some dependencies. Especially the dependency to Cucumber
and JUnit
.
The dependencies need to be fetched from somewhere. Gradle doesn't have a default repository so I specify Maven central.
Then it is time for the magic: Two extensions to the test
task that will allow us to
Gradles default behaviour is to hide stdout and stderr. By specifying testLogging.showStandardStreams =
true
I am able to replace that behaviour with a behaviour that is friendlier to Cucumber users.
I want to be able to send command line arguments to the JVM that will execute the tests. Specifying a
-D
property when running Gradle will only forward that property to the JVM that executes Gradle. This
is probably a good behaviour in some cases, but I want to be able to send arguments to Cucumber from the command
line. The way to do this is to extend the test task with systemProperties System.getProperties()
That's it folks!
The execution will look like this when I run gradle test
$ gradle test :compileJava UP-TO-DATE :processResources UP-TO-DATE :classes UP-TO-DATE :compileTestJava UP-TO-DATE :processTestResources UP-TO-DATE :testClasses UP-TO-DATE :test skeleton.RunCukesTest STANDARD_OUT Feature: Belly Scenario: a few cukes # skeleton/belly.feature:3 Given I have 42 cukes in my belly # Stepdefs.I_have_cukes_in_my_belly(int) When I wait 1 hour Then my belly should growl 1 Scenarios (1 undefined) 3 Steps (2 undefined, 1 passed) 0m0.075s You can implement missing steps with the snippets below: @When("^I wait (\\d+) hour$") public void i_wait_hour(int arg1) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } @Then("^my belly should growl$") public void my_belly_should_growl() throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } BUILD SUCCESSFUL Total time: 2.739 secs
Gradle tries to optimise its execution. If it can't detect any changes, Gradle will view the task as up to date.
This means that there are cases when you won't get the expected output shown above. The way to force Gradle to run
tasks that are up to date is to specify the command line argument --rerun-tasks
.
Like this: gradle test --rerun-tasks
The magic is to extend the test
task with two things.
testLogging.showStandardStreams = true
systemProperties System.getProperties()
I would like to thank Malin Ekholm for proof reading.