Getting started with Cucumber

Following on from GWT syntax and BDD, this post investigates how a Cucumber test is structured, and starts to explore some of the features of Cucumber and Gherkin syntax (the keywords Cucumber uses to execute the tests)

The anatomy of a Cucumber test

Cucumber tests are a lot more complex in structure than JUnit, and rather than explain with code blocks and folder structure here (to copy and paste), you can download a fully working example of a simple Cucumber test project from:

https://github.com/ObjectiveTester/AllThingsTesting.com-examples

The key components are:

The feature file(s)

example: SimpleCucumber/src/test/resources/com/example/simple-maths.feature

As introduced in GWT syntax and BDD, the feature files are the human readable tests – and by that, we mean it’s readable by (possibly slightly less technically minded) humans such as the product owner or business analyst, who will help to contribute scenarios to the tests.

As usual, the example is something simple and familiar – maths operations. The tests are written in plain language such as:

Scenario: Multiplication
    Given I have 2 and 6
    When I multiply the values
    Then The result should be 12

The Gherkin syntax reference details the keywords supported by Cucumber – the example shows some of the common ones, and the documentation lists those plus more advanced features such as Background (for defining preconditions within the features).

The test definition(s)

example: SimpleCucumber/src/test/java/com/example/MathDefinitions.java

These files (although here there’s only one) contain the code implementation of the test steps – for example:

    @When("I multiply the values")
    public void multiply() {
        actual = value1 * value2;
    }

Cucumber matches the ‘When’ clause of the feature to the @When annotation in the test method (and these can also be written to match using regular expressions). The API also supports additional annotations, such as the @Before and @After annotations also present in JUnit. Refer to the Cucumber Reference for more details.

The implementation is specific to the task at hand, and real world tests will be far more complex, almost certainly using additional Java libraries, etc. – this example is very simple.

The runner class

example: SimpleCucumber/src/test/java/com/example/RunTest.java

The runner class defines how Cucumber finds and executes the test, and while the settings here are sufficient for a simple test, the Configuration Options details additional properties (set either via the @CucumberOptions annotation within the class, or via the command line) . The most common of which is the directive to where the feature files are located (for more complex test projects).

The POM file

As this is a Maven project, the pom.xml file defines dependencies and other options. Other build tools are available 😉

Running the tests & reading the results

As with the examples in Getting started with JUnit, the tests can be executed by running mvn test, or from your IDE.

The output to the terminal details the test scenarios executed, and I have included additional debug to record the data table test results. To see how a failure is reported, modify one of the input or expected values (or the tests themselves) and re-run the tests.

Reporting and other advanced options

Cucumber includes a number of report generating plugins, detailed in the reporting documentation. The example uses two built in reporter plugins : pretty – which formats the test results on the command line, and html – which produces a detailed report in:

SimpleCucumber/target/cucumber-report.html

To run a subset of the tests (for example, just a smoke test), it is possible to tag the tests and then instruct the runner class to execute only specific tests. In the example, two of the tests have been tagged as @smoketest – to run only those tests, start the tests with:

mvn test -Dcucumber.filter.tags="@smoketest"

Next Steps

This is a very brief look at the basics of Cucumber – as a learning exercise, I would encourage you to extend the sample with additional tests, experiment with restructuring, and explore some of the additional reporter output options and annotations as detailed in the documentation links.