Behaviour-Driven Development (BDD) with Cucumber, Junit and Spring Boot

Behaviour-Driven Development aka BDD.BDD is a collaborative approach to software development that bridges the communication gap between business and IT. It helps teams create business requirements that can be understood by the whole team. Specifying examples uncovers misunderstandings people might not even be aware of. Teams that practice BDD focus on preventing defects rather than […]

by Nikolay Stanev

September 5, 2018

4 min read

StockSnap DO1KKRFQMB 1 - Behaviour-Driven Development (BDD) with Cucumber, Junit and Spring Boot
Behaviour-Driven Development aka BDD.BDD is a collaborative approach to software development that bridges the communication gap between business and IT. It helps teams create business requirements that can be understood by the whole team. Specifying examples uncovers misunderstandings people might not even be aware of. Teams that practice BDD focus on preventing defects rather than finding them. This leads to less rework and quicker market time.

Benefits of Behaviour-Driven Development

1. Reduces rework caused by misunderstood or vague requirements
2. Reduces technical debt caused by reluctance to refactor code
3. Reduces slow feedback cycles caused by silos and hand-overs
4. Narrows the communication gaps between team members
5. Fosters better understanding of the customer
6. Promotes continuous communication with real world examples

Requirements

For the purpose of this tests I will use STS as workspace and very very important 1.5.12.RELEASE version of Spring. If you use the latest one you will be in trouble. And lastly, the latest version of the Cucumber plugin.

How to write simple test in plain English with Gherkin?

So, enough with the boring definitions. Let’s start with the work part.
The first thing you need to know about BDD with Cucumber is that you write your tests in plain English. The language itself is called Gherkin and resemble something like this:

Scenario: Hearing your snake you anticipate sound
Given I have hungry snake
When When I feed my snake
Then I receive snek snek

As you can see it is plain english. This way you are able to connect your business to your application. What is happening behind is that we are using annotations to mark our test code to the tests.

Dependencies required for this example

First create Spring starter project and change the version of Spring, because it will be set to the latests one.

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.12.RELEASE</version>
<relativePath/>

Then add the dependencies needed for Cucumber and Junit

<dependency>
	<groupId>io.cucumber</groupId>
	<artifactId>cucumber-java</artifactId>
	<version>2.3.1</version>
	<scope>test</scope>
</dependency>

<dependency>
	<groupId>io.cucumber</groupId>
	<artifactId>cucumber-junit</artifactId>
	<version>2.3.1</version>
	<scope>test</scope>
</dependency>

<dependency>
	<groupId>io.cucumber</groupId>
	<artifactId>cucumber-spring</artifactId>
	<version>3.0.2</version>
	<scope>test</scope>
</dependency>
		
<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<scope>test</scope>
</dependency>

Simple functionality representing the test

Now for the purpose of the test we will have simple SnakeController which we will test.

@Controller
public class SnakeController {
	
	private boolean fed;

	@Autowired
	public SnakeController() {
		super();
	}
	
	public void feed()
	{
		fed = true;
	}

	public String poke() {
		if(this.fed == true)
			return "snek snek ^_^";
		else
			return "hiss";
	}
}

File structure and good practices for storing your Gherkin tests. Writing your first test.

Until now – nothing new. Let’s continue to the tests. As I mentioned above all tests that are in the Gherkin language are simple files with .feature extension.You can create them everywhere in your project. It is a good practice to make folder in your src/test/resources and put them there.I prefer to add even a feature folder for personal preference. So you only need to create a file there with the feature extension and start writing tests. You have to end with something like this:

Behaviour-Driven Development

Then let’s add what we want to test in the feature file.
Feature: What does your snake say
I want to use this to check what snake says

Scenario: Hearing your snake you anticipate sound
Given I have hungry snake
When When I feed my snake
Then I receive snek snek

Creating runner responsible for the execution of your tests

We create a simple runner that will run our test code:

@RunWith(Cucumber.class)
@CucumberOptions(plugin = { "pretty"},
		features = { "src/test/resources/features" })
public class TestRunner {


}

Make sure to notice that we are giving the destination of our feature file in the features argument.

The trick part.Creating @SpringBootTest glued to your Gherkin definitions.

Now it is becoming little tricky. We are going to run the tests with Spring so we need to make abstract class that will use the @SpringBootTest functionality and our Cucumber annotated tests are going to use it.

@RunWith(SpringRunner.class)
@SpringBootTest
public abstract class CucumberStepDefinitions {

}

And at last we are gluing our step definitions from our feature file to our test code:

public class SnakeMeasureTest extends CucumberStepDefinitions { 

	@Autowired
	SnakeController snake;
	
	@Given("^I have hungry snake")
	public void i_have_hungry_snake() {
		assertEquals("hiss", snake.poke());
	}

	@When("^When I feed my snake$")
	public void when_i_feed_my_snake() {
		snake.feed();
	}

	@Then("^I receive snek snek$")
	public void receive_snek_snek()  {
		assertEquals("snek snek ^_^", snake.poke());
	}

}

Make sure to note that the Gherkin annotations from the feature file are above our test functions. In the end you have to run your test as simple Junit test and you should receive something like this in your console:

Behaviour-Driven Development

I hope you find the information useful. If you like what you have just read or have any questions, hit the comment button below.

Categories