JVM Advent

The JVM Programming Advent Calendar

Writing BDD tests with Cucumber JVM

Cucumber JVM as an excellent tool to write your BDD tests.In this article I would like to give an introduction to BDD with Cucumber JVM.

Let’s get started…

What is BDD?

problems

In a nutshell, BDD tries to solve the problem of “understanding requirements with examples”
bdd

BDD tools
There are lot of tools available for BDD and interestingly you can find quite a few vegetable names in the list 😉 Cucumber,Spinach, Lettuce, JBehave, Twist etc. Out of these Cucumber is simple and easy to use.

Cucumber-JVM
Cucumber is written in Ruby and Cucumber JVM is an implementation of cucumber for the popular JVM languages like Java, Scala, Groovy, Clojure etc

Cucumber Stack
stack
We write features and scenarios in a “Ubiquitous” Language and then implement them with the step definitions and support code.

Feature file and Gherkin
You first begin by writing a .feature file.A feature file conventionally starts with the Feature keyword followed by Scenario. Each scenario consists of multiple steps. Cucumber uses Gherkin for this. Gherkin is a Business Readable, Domain Specific Language that lets you describe software’s behavior without detailing how that behavior is implemented.
Example:

Feature: Placing bets       
 Scenario: Place a bet with cash balance         
 Given I have an account with cash balance of 100        
 When I place a bet of 10 on "SB_PRE_MATCH"      
 Then the bet should be placed successfully      
 And the remaining balance in my account should be 90

As you can see the feature file is more like a spoken language with gherkin keywords like Feature, Scenario, Given,When, Then,And ,But, #(for comments).

Step Definitions
Once you have finalized the feature file with different scenarios, the next stage is to give life to the scenarios by writing your step definitions. Cucumber uses regular expression to map the steps with the actual step definitions. Step definitions can be written in the JVM language of your choice. The keywords are ignored while mapping the step definitions.
So in reference to the above example feature we will have to write step definition for all the four steps. Use the IDE plugin to generate the stub for you.

import cucumber.api.java.en.And;        
import cucumber.api.java.en.Given;       
import cucumber.api.java.en.Then;        
import cucumber.api.java.en.When;        
public class PlaceBetStepDefs {      
 @Given("^I have an account with cash balance of (\\d+) $")      
 public void accountWithBalance(int balance) throws Throwable {      
 // Write code here that turns the phrase above into concrete actions        
 //throw new PendingException();         
 }       
 @When("^I place a bet of (\\d+) on \"(.*?)\"$")         
 public void placeBet(int stake, String product) throws Throwable {      
 // Write code here that turns the phrase above into concrete actions        
 // throw new PendingException();        
 }       
 @Then("^the bet should be placed successfully$")        
 public void theBetShouldBePlacedSuccessfully() throws Throwable {       
 // Write code here that turns the phrase above into concrete actions        
 //throw new PendingException();         
 }       
 @And("^the remaining balance in my account should be (\\d+)$")      
 public void assertRemainingBalance(int remaining) throws Throwable {        
 // Write code here that turns the phrase above into concrete actions        
 //throw new PendingException();         
 }       
}

Support Code
The next step is to back your step definitions with support code. You can for example do a REST call to execute the step or do a database call or use a web driver like selenium . It is entirely up to the implementation. Once you get the response you can assert it with the results you are expecting or map it to your domain objects.
For example you can you selenium web driver to simulate logging into a site

protected WebDriver driver;         
@Before("@startbrowser")         
public void setup() {        
 System.setProperty("webdriver.chrome.driver", "C:\\devel\\projects\\cucumberworkshop\\chromedriver.exe");      
 driver = new ChromeDriver();        
}        
@Given("^I open google$")        
public void I_open_google() throws Throwable {       
 driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);         
 driver.get("https://www.google.co.uk");         
}

Expressive Scenarios
Cucumber provides more options to organize your scenarios better.

  • Background– use this to define steps which are common to all scenarios
  • Data Tables– You can write the input data in table format
  • Scenario Outline-placeholder for your scenario which can be executed for a set of data called Example.
  • Tags and Sub Folders to organize your features-Tags are more like sticky notes for documentation.

Dependency Injection
More often than not you might have to pass the information created in one step to another. For example you create a domain object in your first step and then you need to use it in your second step. The clean way to achieve this is through Dependency Injection . Cucumber provides modules for the main DI containers like Spring, Guice, Pico etc.

Executing Cucumber
It is very easy to run Cucumber on IntelliJ IDE . It can be also integrated with your build system. You can also control the tests you want to run with different options.

Reporting Options
There are lot of plugins available for reporting . For example you could use the Master Thought plugin for the reports.

References
The Cucumber for Java book– This is an excellent book and this is all you need to get you started
Documentation
GitHub link
That’s all folks. Hope you liked it. Have a good Christmas! Enjoy.

Author: lakshmihm

I am senior java developer with around 10 years experience. I mainly work on java backend and like exploring different JVM technologies
I am strong follower of agile best practices . I am always aiming to develop software which is clean in design, does what the user wants and is performance efficient.

Next Post

Previous Post

2 Comments

  1. Alexander Turner December 3, 2015

    Hi,

    Nice article which I am still reading through. I love reading about this sort of technology. Nevertheless, I had to go look up with BDD is. Now, I might be a dinosaur (or even an elephant) because I started coding in the 1980s etc, but I can say with some confidence that a lot of very good, cutting edge, Java is written without BDD so there are a lot of out there who could do with a brief introduction somewhere in your post.

    On another, possibly more interesting note: Can one integrate Cumber and JMH thereby making performance BDD tests which work. Like, “Give it is Black Friday”, “Spare servers will spin up”,”Then the site can take 100 000 transactions a minute”. I guess one could make a ‘Turin complete so yes’ type argument – but is there any easy/clean way. That might be seriously interesting.

    Thanks – AJ

    • lakshmihm December 4, 2015 — Post Author

      Hi Alexander,

      Thanks for the comments.

      In my humble opinion I am not sure if it is a good idea to use BDD for performance tests.
      As in BDD is more about understanding the requirements without introducing any technical jargon.

      But actually you are correct!!
      I am came across this link stackoverflow which says exactly the same. Great Idea.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2024 JVM Advent | Powered by steinhauer.software Logosteinhauer.software

Theme by Anders Norén