BDD Testing in Java with Cucumber
Table of Contents

BDD Testing in Java with Cucumber

Cucumber is a tool that supports Behaviour Driven Development (BDD). It enables one common language between IT and non-technical persons for creating up-front application feature specifications and desired behavior. In other words, it facilitates good cooperation between all project participants, such as developers, product owners, business analysts, and testers. There is a clear separation between natural language and test code, making it easier to write and read the specs for all, not just developers.

Cucumber is well-suited for large integrations or end-to-end tests involving many working components and microservices, as well as interactions between people with different skills and backgrounds. You can run so-called "platform tests" that check larger chunks of your business flows with many counterparts involved. Afterwards, a nice human-readable report will be automatically generated. If you are interested in more details, let's dive deeper.

Pre-requirements:

  • Install IntelliJ plugin "Cucumber for Java"
  • Create a sample project:
mvn archetype:generate \ 
   "-DarchetypeGroupId=io.cucumber"\ 
   "-DarchetypeArtifactId=cucumber-archetype" \ 
   "-DarchetypeVersion=7.11.2" \ 
   "-DgroupId=hellocucumber" \ 
   "-DartifactId=hellocucumber" \ 
   "-Dpackage=hellocucumber" \ 
   "-Dversion=1.0.0-SNAPSHOT" \ 
   "-DinteractiveMode=false" 

Testing with Cucumber

Working with Cucumber consists of three steps:  

A. Write feature test steps in Gherkin

B. Write "glue" code

C. Write application code.

Let's dive into each.

A. Write Feature Test Steps in Gherkin.

To start, you need to write the new feature specification in the DSL Gherkin. It should be a human-readable statement explaining the expected behavior of the new feature. Include a range of cases: optimistic, pessimistic, and corner cases at the end.

Gherkin's most common keywords are:

Feature, Rule, Example, Given, When, Then, And, But, Background, Scenario, Scenario Outline, Examples.

For a simple example, we could write a ".feature" file (".feature" is the file extension of Cucumber files) like this:

Scenario: Friday 
		Given today we have "Friday" 
		When I check if it is the last week's working day 
		Then I will get the response "It's Friday, Friday, Gotta get down on Friday" 
Scenario: Monday 
    Given today we have "Monday" 
    When I check if it is the last week's working day 
    Then I will get the response "Not yet" 

You can include as many Given/When/Then statements as you need, depending on your test requirements in a given context. Gherkin's format helps non-technical people understand the test file content, which is one of its biggest strengths.  

B. Write "Glue" Code

Each step from the ".feature" file needs to know which code (application or test) should be run, which is why "glue" code is necessary. Luckily, you can automatically generate all "glue" method definitions using the IntelliJ plugin "Cucumber for Java." In the ".feature" file, point the cursor to the step and press "Alt + Insert" -> "Create step definition." You may also just ask Copilot to write the code for you.

Alternatively, you can run the feature test and copy all missing "glue" methods listed in the output. You only need to add the methods' implementation manually. Note that in the glue classes, we use private fields to exchange data between steps.

public class WeekDayStepsDefinitions { 

    private String today; 

    private String response; 

  

    @Given("today we have {string}") 

    public void todayWeHave(String day) { 

        today = day; 

    } 

  

    @Then("I will get response {string}") 

    public void iWillGetResponse(String expectedResponse) { 

        assertEquals(response, expectedResponse); 

    } 

  

    @When("I check if there is last week working day") 

    public void iCheckIfThereIsLastWeekWorkingDay() { 

        response = WeekdayService.isItFriday(today); 

    } 

} 

  

C. Write Application Code   

Finally, following the BDD methodology, we implement a simple domain service that we want to test.

public class WeekdayService { 

    public static String isItFriday(String today) { 

        return "Friday".equals(today) ? "Friday, Friday, gotta get down on Friday" : "Not yet"; 

    } 

} 

Of course, you will need to add the necessary dependencies in the pom file. The most important ones are:

<dependency> 

    <groupId>io.cucumber</groupId> 

    <artifactId>cucumber-java</artifactId> 

    <scope>test</scope> 

</dependency> 

<dependency> 

    <groupId>io.cucumber</groupId> 

    <artifactId>cucumber-java8</artifactId><!-- To work with lambda glue style--> 

    <scope>test</scope> 

</dependency> 

<dependency> 

    <groupId>io.cucumber</groupId> 

    <artifactId>cucumber-junit-platform-engine</artifactId><!-- To work with Junit 5--> 

    <scope>test</scope> 

</dependency> 

That's it. We just wrote the first Cucumber BDD test. Now run it (mvn test) and check the HTML report inside the target folder with test and step results summary.

Now we are ready to explore more Cucumber elements.   

Lambda-Style Testing

There is an option to write step definitions in a more concise form using Java 8 lambda functions. The glue code could then be as follows, with the rest remaining the same.

public class WeekdayLambdaStepsDefinitions implements En { 

    private String today; 

    private String response; 

  

    public WeekdayLambdaStepsDefinitions() { 

        Given("today we have {string}", (String day) -> today = day); 

  

        When("I check if there is the last week's working day", () -> response = WeekdayService.isItFriday(today)); 

  

        Then("I will get response {string}", (String expectedResponse) -> 

                Assertions.assertEquals(response, expectedResponse)); 

    } 

} 

Running Tests with Multiple Parameters.

In case you need to run the test multiple times with different parameters, you can create a "Scenario Outline" with "Examples." See the example below:

 Given today we have "<day>" 

  When I check if there is the last week's working day 

  Then I will get response "<answer>" 

  Examples: 

    | day            | answer      | 

    | Friday         | Yes finally | 

    | Monday         | Not yet     | 

    | Sunday         | Not yet     | 

    | Not existing value | Not yet     | 

Passing Multiple Pieces of Data Inside Steps.

To pass a list of values to a step definition, "Data Tables" are handy. In the glue code, you can then transform them into Lists and Maps of simple or Domain elements.

Given the following users exist: 

| name    | email                | nick   | 

| Andrew  | andrew@cucumber.io   | andrew | 

| John    | jon@cucumber.io      | john   | 

| Smith   | smith@cucumber.io    | smith  | 

If you want to set this up before each test feature scenario, move the "Given" section into the "Feature: Background:" instead of the "Scenario."

Background: This will run before each feature scenario 

  Given the following users exist: 

    | name   | email              | nick   | 

    | Andrew | andrew@cucumber.io | andrew | 

    | Jon    | jon@cucumber.io    |        | 

    | Smith  | smith@cucumber.io  | smit   | 

Conclusion.

Cucumber is a fantastic BDD tool for facilitating collaboration between technical and non-technical stakeholders. Based on a single specification file, each feature provides:

  • Requirements – written as a structured list with all behaviors before development starts
  • Better collaboration – encourages collaboration between all project stakeholders
  • Test scenarios – includes both optimistic and edge case scenarios to be tested
  • Acceptance criteria – can define the "done" for Scrum tasks and list the behaviors we want to implement and check
  • Test documentation – helps new team members understand the main application flow quickly
  • Improved quality – by defining clear requirements and testing against them, Cucumber helps identify defects earlier, leading to better software

Using Cucumber does not guarantee non-technical colleagues will want to write specifications in Gherkin. In this case, you could consider BDD Spock, which requires less maintenance since the test specification and implementation are in the same file, not two separate ones.

Passing all Cucumber tests doesn't mean the application is entirely bug-free. Be careful not to fall into a false sense of security. The tool is an excellent choice for tests with a large scope, like end-to-end integrations, where you want to work actively on a technical-free document that outlines your system's flows with many modules underneath and involves stakeholders with various backgrounds.

Testing is a crucial step of the software development lifecycle. Contact us today to create high-quality Java applications together.

Liked the article? subscribe to updates!
360° IT Check is a weekly publication where we bring you the latest and greatest in the world of tech. We cover topics like emerging technologies & frameworks, news about innovative startups, and other topics which affect the world of tech directly or indirectly.

Like what you’re reading? Make sure to subscribe to our weekly newsletter!
Relevant Expertise:
No items found.
Share

Subscribe for periodic tech i

By filling in the above fields and clicking “Subscribe”, you agree to the processing by ITMAGINATION of your personal data contained in the above form for the purposes of sending you messages in the form of newsletter subscription, in accordance with our Privacy Policy.
Thank you! Your submission has been received!
We will send you at most one email per week with our latest tech news and insights.

In the meantime, feel free to explore this page or our Resources page for eBooks, technical guides, GitHub Demos, and more!
Oops! Something went wrong while submitting the form.

Related articles

Our Partners & Certifications
Microsoft Gold Partner Certification 2021 for ITMAGINATION
ISO-IEC 27001:2013 ITMAGINATION ISO 9001 ITMAGINATION
© 2024 ITMAGINATION, A Virtusa Company. All Rights Reserved.