Spring Boot Cucumber Tests Example

In this post, we feature a comprehensive article on Spring Boot Cucumber Tests. We will create a Spring Boot rest application and test the spring boot application with cucumber acceptance testing.

1. Introduction

Spring Boot is an open source Java-based framework used to create a micro Service. It is developed by Pivotal Team and is used to build stand-alone and production ready spring applications. Spring Boot provides a good platform for Java developers to develop a stand-alone and production-grade spring application that you can just run. You can get started with minimum configurations without the need for an entire Spring configuration setup. Spring Boot automatically configures your application based on the dependencies you have added to the project by using @EnableAutoConfiguration annotation. It has starter configurations for various entities.

Want to master Spring Framework ?
Subscribe to our newsletter and download the Spring Framework Cookbook right now!
In order to help you master the leading and innovative Java framework, we have compiled a kick-ass guide with all its major features and use cases! Besides studying them online you may download the eBook in PDF format!

Thank you!

We will contact you soon.

Acceptance test ensures that the right things are built. Automated acceptance testing is one of the principles of Extreme programming. Cucumber tries to address the area of acceptance testing. Cucumber allows collaboration between business stakeholder and development team to express the business outcomes. Cucumber has its own ubiquitous language and adheres to syntax rules known as Gherkin. We will take a look at how cucumber fits in with Selenium ecosystem. It is a Business Readable, Domain Specific Language that lets you describe software’s behavior without detailing how that behavior is implemented. These are the following constructs of the Gherkin language.

2. Spring Boot Application

We will implement a calculator web service and automate testing with Cucumber. Our focus is on Automated Acceptance testing and not unit testing the application. We will first look at the Gradle configuration and the corresponding initializers for Spring Boot. Gradle is the build and dependency manager used in our current project.

build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group 'com.jcg'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.4.RELEASE")
    }
}
dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
    testCompile group: 'io.cucumber', name: 'cucumber-java', version: '4.3.0'
    testCompile group: 'io.cucumber', name: 'cucumber-junit', version: '4.3.0'
    testCompile group: 'junit', name: 'junit', version: '4.12'
    testCompile group: 'io.cucumber', name: 'cucumber-spring', version: '4.3.0'
    testCompile 'org.springframework.boot:spring-boot-starter-test'
}

We will create a SpringBoot application using the below code. SpringCucumberApplication

@SpringBootApplication
public class SpringCucumberApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCucumberApplication.class, args);
    }
}

Let us implement our simple Calculator using Spring Rest. Calculator.java

@RestController
@RequestMapping("/calc")
public class Calculator {
    @RequestMapping("/add")
    public int add(int a, int b) {
        return a + b;
    }
    @RequestMapping("/sub")
    public int subtract(int a, int b) {
        return a - b;
    }
    @RequestMapping("/mul")
    public int multiply(int a, int b) {
        return a * b;
    }
    @RequestMapping("/div")
    public int divide(int a, int b) {
        return a / b;
    }
}

By default, SpringBoot starts up in port 8080 which can be changed by specifying the port in application.properties as below. application.properties

server.port=8082

We can test our application by running the SpringCucumberApplication. We can check the application by navigating to the URL which prints the result as 5.

3. Cucumber Acceptance Testing

In this section, We will work on creating test cases for the endpoints created. The first step is to create a feature file capturing all the testing scenarios. calc.feature

Feature: arithmetic operations
  Scenario: client wants to add two numbers
    When the client calls /calc/add with values 1 and 2
    Then the client receives answer as 3
  Scenario: client wants to subtract two numbers
    When the client calls /calc/sub with values 5 and 3
    Then the client receives answer as 2
  Scenario: client wants to divide two numbers
    When the client calls /calc/div with values 6 and 2
    Then the client receives answer as 3

To kick off the test execution, a Spring Boot Execution class has to be created and configured under the test directory. CalculatorTest.java

@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources")
public class CalculatorTest {
}

This specifies that the test suite has to be run with Cucumber runner and Cucumber has to identify the feature file under the parent directory specified with features options. Cucumber looks for a features folder under the directory for the presence of .feature files. Running the above class produces the following output.

Undefined scenarios:
src/test/resources/features/calculator.feature:3 # client wants to add two numbers
src/test/resources/features/calculator.feature:7 # client wants to subtract two numbers
src/test/resources/features/calculator.feature:11 # client wants to divide two numbers
....
@When("the client calls \\/calc\\/add with values {int} and {int}")
public void the_client_calls_calc_add_with_values_and(Integer int1, Integer int2) {
    // Write code here that turns the phrase above into concrete actions
    throw new cucumber.api.PendingException();
}
@Then("the client receives answer as {int}")
public void the_client_receives_answer_as(Integer int1) {
    // Write code here that turns the phrase above into concrete actions
    throw new cucumber.api.PendingException();
}
@When("the client calls \\/calc\\/sub with values {int} and {int}")
public void the_client_calls_calc_sub_with_values_and(Integer int1, Integer int2) {
    // Write code here that turns the phrase above into concrete actions
    throw new cucumber.api.PendingException();
}
@When("the client calls \\/calc\\/div with values {int} and {int}")
public void the_client_calls_calc_div_with_values_and(Integer int1, Integer int2) {
    // Write code here that turns the phrase above into concrete actions
    throw new cucumber.api.PendingException();
}

It has the structure for the missing steps which can be implemented in a new class. This is exactly moved into a StepDefinition Class as below CalculatorStepDefinitions.java

public class CalculatorStepDefinitions extends SpringIntegrationTest {
    int response = 0;
    String url = DEFAULT_URL + "calc/";
    @When("the client calls \\/calc\\/add with values {int} and {int}")
    public void the_client_calls_arithmetic_add_with_values_and(int int1, int int2) {
        response = restTemplate.getForObject(url + "add?a=" +
                int1 + "&b=" + int2, Integer.class);
    }
    @Then("the client receives answer as {int}")
    public void the_client_receives_answer_as(int result) {
        assertEquals(result, response);
    }
    @When("the client calls \\/calc\\/sub with values {int} and {int}")
    public void the_client_calls_calc_sub_with_values_and(Integer int1, Integer int2) {
        response = restTemplate.getForObject(url + "sub?a=" +
                int1 + "&b=" + int2, Integer.class);
    }
    @When("the client calls \\/calc\\/mul with values {int} and {int}")
    public void the_client_calls_calc_mul_with_values_and(Integer int1, Integer int2) {
        response = restTemplate.getForObject(url + "mul?a=" +
                int1 + "&b=" + int2, Integer.class);
    }
    @When("the client calls \\/calc\\/div with values {int} and {int}")
    public void the_client_calls_calc_div_with_values_and(Integer int1, Integer int2) {
        response = restTemplate.getForObject(url + "div?a=" +
                int1 + "&b=" + int2, Integer.class);
    }
}

We will look at the base class below as that provides the Spring configuration for the Step definition class to be executed. SpringIntegrationTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(
        classes = SpringCucumberApplication.class,
        webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public abstract class SpringIntegrationTest {
    protected RestTemplate restTemplate = new RestTemplate();
    protected final String DEFAULT_URL = "http://localhost:8082/";
}

Now running the class CalculatorTest produces the following output

Cucumber Scenario Output

4. Cucumber Scenario Outline

In the previous section, We saw tests with a single data point. But if we wanted to test the same scenario with multiple data points, Cucumber provides the option of a Scenario Outline. We have to modify our feature file to create a Scenario Outline. calc.feature

Feature: arithmetic operations...
Scenario Outline: client wants to multiply two numbers
    When the client calls /calc/mul with values  and 
    Then the client receives answer as 
    Examples:
      | number1 | number2 | result |
      | 2       | 3       | 6      |
      | 4       | 6       | 24     |
      | 7       | 8       | 56     |

As specified in the above section, to execute the scenario we need to update the CalculatorStepDefinitions class CalculatorStepDefinitions.java

public class CalculatorStepDefinitions extends SpringIntegrationTest {
...
 @When("the client calls \\/calc\\/mul with values {int} and {int}")
    public void the_client_calls_calc_mul_with_values_and(Integer int1, Integer int2) {
        response = restTemplate.getForObject(url + "mul?a=" +
                int1 + "&b=" + int2, Integer.class);
    }
}

This is similar to the other methods except that here we are calling the Multiply endpoint. Once we now execute the CalculatorTest, we get the output as below

Cucumber Scenario Outline Output

5. Download the Source Code

Download
You can download the full source code of this example here: Spring Boot Cucumber Tests
Exit mobile version