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?
In a nutshell, BDD tries to solve the problem of “understanding requirements with examples”
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
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.
Reference: | Writing BDD tests with Cucumber JVM from our JCG partner lakshmihm at the Java Advent Calendar blog. |