Part 1 - Initial Setup: Cucumber-JVM via Gradle

Part 1 - Initial Setup: Cucumber-JVM via Gradle

A getting started guide to Cucumber-JVM

·

4 min read

Skip ahead and view:

Overview

We'll create a basic Cucumber project that:

  • Uses the Cucumber for Java IDE plugin for test case development

  • A custom Gradle task running the Cucumber CLI via JavaExec

  • Utilises dependency injection to store state across scenario steps that reside in different classes

This will be split across a few posts so it doesn't drag on too long.

In future posts, we'll also fork this project and build upon it in a few different directions including:

  • Passing in system properties to control settings (eg to allow better flexibility with Jenkins pipelines and different styles of tests)

  • Adding the ability to run REST tests using RestAssured

  • Adding support to run browser-based tests in Chrome and Firefox

  • Use Gradle modules to separate sub-projects

  • Switching the way we run our tests from JavaExec across to JUnit

Pre-requisites

  • JDK 8+ installed

  • GIT configured

  • IntelliJ (or equivalent IDE) installed

  • The "Cucumber for Java" Plugin is installed (File > Settings > Plugins > MarketPlace > Search for "Cucumber for Java" and click Install. Restart the IDE).

  • Clone https://github.com/cucumber/cucumber-java-skeleton into a directory

  •             cd <directory-you-wish-to-create-new-project-in>
                git clone https://github.com/cucumber/cucumber-java-skeleton.git
    

Assumptions

We assume that:

  • you have at least a Comp 101 understanding of Java

  • you are using IntelliJ. If not adjust accordingly.

Note formal documentation can be found at https://cucumber.io/docs/cucumber/

What is Cucumber & Why Do I Need It?

Cucumber is a testing tool that supports the Behaviour Driven Development (BDD) style of tests, using the Gherkin syntax. It allows Quality Assurance teams to build tests that align with the story pattern of Agile development, although at a more granular level of course. This ensures:

  • user behaviour throughout the test is defined clearly

  • the outcome of the test is clear

  • complex tests can be simply understood by anyone on the team.

Let's demonstrate with a super simple example. In this case:

  • we have a web application that allows users to log in and update their email

  • we are testing the UI only. The code is using a REST API and we test the patch scenario separately to ensure

Assumptions:

  • as part of the test provisioning, we create a user for this test specifically (in the real world, you would like to want to create the user via a REST API at the start of the test if possible)

  • this user is ephemeral

Story

Scenario: As a user, I can log in to my account and update my email address successfully

Scenario Steps:

Scenario: As a user, I can login to my account and update my email address successfully
Given the user logs into the site with the 'testuser' username and 'Testpass1234' password
* the user clicks on the user avatar in the top right of the page
* the user clicks the 'Account' link
* the user verifies that the 'Email' input has the value 'test@user.com'
When the user enters 'mynewemail@user.com' into the 'Email' input
* the user clicks the Update button
Then the success message 'Profile updated' is displayed at the top of the page
* the user reloads the page
* the user verifies that the 'email' input has the value 'mynewemail@user.com'

Notice the use of "*", this is an acceptable way of grouping steps that belong to the same level without the typical repetition of Given, And, When, Then that you typically see in stories.

As you can see, this outlines exactly what the test is doing and anyone on the team should be able to read and understand the test outcome. If it repeatedly fails at a particular step, then it is pretty clear what could be broken.

Now, let's get underway.

Clone the Project

Import the cloned project into IntelliJ, and you should see:

There are multiple ways of running Cucumber tests, including via JUnit 5, JUnit 4 or via a custom Gradle task with JavaExec using the CLI. In addition, when developing your feature files you can run it via the Cucumber for Java plugin within IntelliJ.

For this tutorial, we are going to use Gradle tasks + JavaExec for the command line, and of course Cucumber for Java. In upcoming tutorials.

Let's remove the .github / maven folders and move everything under the gradle file up one level (you might need to rename the top-level gradle folder first). Once you've done so, run the following command to build / import dependencies:

./gradlew

Your project should look like this:

Test the Initial Scenario

Open up the belly.feature under src/test/resources/io.cucumber.skeleton and comment on the lines 5 and 6 that haven't been implemented yet (CTRL + /).

Right-click on belly.feature and select "Run" (if you don't see this, ensure the Cucumber for Java plugin is installed):

If everything is configured, then you should see the single-step pass. To see the step break-down, ensure you select "Show Passed" in the Run window:

Woohoo - the base configuration is working and can be run via Cucumber for Java.

Now it is time to start customising things. Let's start doing that in Part 2 (coming soon).