What is Cucumber Testing? A Guide To Testing With Cucumber Tool
In this blog, we will walk you through the essentials of setting up Cucumber for your project. You will learn about the prerequisites, installation steps, and configuration needed to get Cucumber up and running. This guide will provide clear instructions for various environments, ensuring you have everything you need to start writing your first Cucumber tests.
What is Cucumber?
Cucumber is an open-source software tool used for behavior-driven development (BDD). It allows developers, testers, and business stakeholders to write test scenarios in plain language that anyone can understand, typically using the Gherkin language. This plain language approach enables non-technical team members to participate actively in the testing process, ensuring that the software behaves as expected from a user's perspective.
Cucumber supports multiple programming languages, including Java, Ruby, and JavaScript, and it integrates with many test automation frameworks like JUnit, TestNG, and RSpec. The primary goal of Cucumber is to enhance collaboration between technical and non-technical teams by fostering a shared understanding of how the application should work.
What is BDD Testing?
Cucumber is primarily used for BDD testing. So what's exactly is BDD testing?
BDD testing is an Agile methodology where test cases are crafted in straightforward language, making them accessible even to those without technical expertise. The primary aim of BDD testing is to foster collaboration between the technical and business teams within an organization.
The Gherkin language, used in BDD, is a business-readable syntax designed to describe system behaviors and scenarios. It is structured around three core statements: Given, When, and Then, each outlining a specific part of the system's behavior.
- The Given statement establishes the initial context and defines the starting conditions of the system.
- The When statement details the action or event that triggers a change in the system.
- The Then statement specifies the expected outcome following the action described in the When statement.
BDD testing is rooted in the idea that the "tres amigos" (three key roles) in software development often have different perspectives, and establishing common ground is essential for effective communication. The "tres amigos" are:
- Product Owner: Represents the business side, focusing on solving a particular problem.
- Developer: Represents the development side, aiming to build a solution that addresses the problem identified by the Product Owner.
- Tester: Represents the QA side, ensuring the solution effectively solves the problem and identifying potential issues.
Traditional testing approaches often fail to connect these perspectives. Typically, stakeholders relay their requirements to the Product Owner, who then communicates them to developers and testers. Developers translate these requirements into code, while testers convert them into test cases. This sequential process is time-consuming and can lead to miscommunication and misunderstandings.
In contrast, BDD encourages the "tres amigos" to collaborate directly, discussing the requirements together and documenting their insights using a shared language. This collaborative approach ensures a common understanding of the problem and allows testers to create test cases using a BDD framework, reducing the risk of misunderstandings and improving the overall development process.
Read More: What is BDD Testing?
How Does Cucumber Work?
Cucumber operates through a process that bridges the gap between human-readable specifications and automated testing code.
Step 1: Gherkin Language Parsing
Cucumber begins by reading feature files written in Gherkin, a language that uses plain English-like syntax to describe software behavior. Each feature file contains one or more scenarios that describe different use cases or functionalities of the application.
The Gherkin syntax is parsed into a structured format that Cucumber can understand, breaking down the scenarios into individual steps such as Given, When, and Then
Step 2: Step Definition Mapping
Each step in the Gherkin file is mapped to a corresponding piece of code, known as a step definition. These are written in a programming language (e.g., Java, Ruby, Python) and include logic that interacts with the application under test. Cucumber uses annotations (such as @Given, @When, @Then in Java) to bind Gherkin steps to specific methods in the code. When Cucumber parses a step like “Given the user is on the login page,” it looks for a method annotated with @Given that matches the text.
Here’s an example of how Gherkin steps are mapped to step definitions in Cucumber. Let's say we have this feature file:
Feature: User Login
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters a valid username and password
Then the user should be redirected to their dashboard
We have the following code:
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
public class LoginSteps {
@Given("the user is on the login page")
public void the_user_is_on_the_login_page() {
// Code to navigate to the login page
System.out.println("User navigates to the login page.");
}
@When("the user enters a valid username and password")
public void the_user_enters_a_valid_username_and_password() {
// Code to enter username and password
System.out.println("User enters valid credentials.");
}
@Then("the user should be redirected to their dashboard")
public void the_user_should_be_redirected_to_their_dashboard() {
// Code to verify redirection to the dashboard
System.out.println("User is redirected to the dashboard.");
}
}
As you can see, the “Given the user is on the login page” Gherkin step is mapped to the @Given annotation. The same applies to other steps.
Step 3: Test Execution
To run Cucumber tests, you need a test runner. You can create a class that will be the entry point for running your Cucumber tests. The test runner class here uses JUnit's @RunWith annotation to specify that JUnit should run the tests, and the @CucumberOptions annotation to configure the execution.
import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources/features")
public class RunCucumberTest {
}
When executing, you can run the test runner class directly from your IDE, or use Maven or Gradle to run the tests (mvn test for Maven or gradle test for Gradle).
Examples of Cucumber Tests
Let's say you are testing a banking application which allows users to log in to their accounts using a username and password. The goal is to ensure that only registered users with the correct credentials can log in, and users with incorrect credentials are denied access.
We'll start by writing a feature file that describes the behavior of the login functionality in plain language.
Feature: User Login
As a registered user of the banking application,
I want to log in to my account
So that I can access my personal banking dashboard
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters a valid username and password
And clicks the login button
Then the user should be redirected to their banking dashboard
Scenario: Unsuccessful login with invalid credentials
Given the user is on the login page
When the user enters an invalid username or password
And clicks the login button
Then the user should see an error message indicating invalid login credentials
Scenario: Unsuccessful login with empty credentials
Given the user is on the login page
When the user leaves the username or password field empty
And clicks the login button
Then the user should see an error message indicating that both fields are required
The next step is to write the step definitions that will map the Gherkin steps to the actual code that interacts with the application. Below is an example of how you might write these in Java.
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
import static org.junit.Assert.*;
public class LoginSteps {
private LoginPage loginPage;
private DashboardPage dashboardPage;
private String errorMessage;
@Given("the user is on the login page")
public void the_user_is_on_the_login_page() {
loginPage = new LoginPage();
loginPage.navigateToLoginPage();
}
@When("the user enters a valid username and password")
public void the_user_enters_a_valid_username_and_password() {
loginPage.enterUsername("validUser");
loginPage.enterPassword("validPassword");
}
@When("the user enters an invalid username or password")
public void the_user_enters_an_invalid_username_or_password() {
loginPage.enterUsername("invalidUser");
loginPage.enterPassword("invalidPassword");
}
@When("the user leaves the username or password field empty")
public void the_user_leaves_the_username_or_password_field_empty() {
loginPage.enterUsername("");
loginPage.enterPassword("");
}
@When("clicks the login button")
public void clicks_the_login_button() {
loginPage.clickLoginButton();
}
@Then("the user should be redirected to their banking dashboard")
public void the_user_should_be_redirected_to_their_banking_dashboard() {
dashboardPage = new DashboardPage();
assertTrue(dashboardPage.isDashboardDisplayed());
}
@Then("the user should see an error message indicating invalid login credentials")
public void the_user_should_see_an_error_message_indicating_invalid_login_credentials() {
errorMessage = loginPage.getErrorMessage();
assertEquals("Invalid username or password.", errorMessage);
}
@Then("the user should see an error message indicating that both fields are required")
public void the_user_should_see_an_error_message_indicating_that_both_fields_are_required() {
errorMessage = loginPage.getErrorMessage();
assertEquals("Username and password are required.", errorMessage);
}
}
Once the feature file and step definitions are set up, you can run the Cucumber tests. In most setups, this is done using a test runner (e.g., JUnit in Java).
import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/resources/features",
glue = "com.example.steps",
plugin = {"pretty", "html:target/cucumber-reports"},
monochrome = true
)
public class RunCucumberTest {
}
Benefits of using Cucumber For Testing
1. Enhanced Collaboration Between Teams: Cucumber’s use of plain language (Gherkin) allows for seamless collaboration between technical and non-technical team members. Business stakeholders, product owners, and QA teams can all participate in the writing and review of feature files, ensuring that everyone is on the same page regarding the software’s expected behavior. This collaborative approach helps prevent misunderstandings and ensures that the final product meets the requirements of all stakeholders.
2. Improved Communication with Non-Technical Stakeholders: One of the standout features of Cucumber is its ability to communicate requirements in a language that non-technical stakeholders can understand. By using Gherkin syntax, which reads almost like plain English, Cucumber bridges the gap between technical and non-technical team members. This means that even those without a technical background can write, read, and understand the tests, fostering better communication and reducing the chances of misinterpretation of requirements.
3. Behavior-Driven Development (BDD) Support: Cucumber is inherently designed to support Behavior-Driven Development (BDD), a methodology that focuses on specifying the behavior of software rather than just its implementation. This focus on behavior ensures that the software is developed with the end-user in mind, leading to products that better meet user needs and are more aligned with business goals. By integrating BDD practices, teams can ensure that they are building the right features in the right way.
4. Readable and Maintainable Tests: Tests written in Cucumber are typically more readable and maintainable than traditional unit tests. The use of Gherkin language makes the tests self-explanatory, reducing the need for extensive comments or documentation. Additionally, because the tests are written from the user's perspective, they tend to be more intuitive, making it easier for new team members to understand and work with them.
Cucumber Testing Best Practices
1. Write Clear and Concise Scenarios: Ensure that your Gherkin scenarios are straightforward, focusing on one behavior per scenario. Avoid complex, multi-step scenarios that might be difficult to maintain.
2. Reuse Step Definitions: Create reusable step definitions to avoid duplication. This not only makes the code DRY (Don’t Repeat Yourself) but also ensures consistency across scenarios.
3. Keep Feature Files Business-Focused: Feature files should be understandable to non-technical stakeholders. Use language that reflects the business domain and avoid implementation details.
4. Organize Feature Files and Step Definitions: Maintain a clear structure by organizing feature files into logical subdirectories and grouping related step definitions together.
5. Leverage Data Tables and Scenario Outlines: Use data tables and scenario outlines to handle multiple test cases efficiently, reducing the need for repetitive scenarios while covering a wide range of inputs.
How To Automate Cucumber Testing?
Katalon is a comprehensive automation testing tool that enables QA teams to:
👉 Create codeless tests
👉 Manage them in a centralized repository
👉 Execute tests across multiple browsers in the cloud
👉 Produce detailed reports for data-driven decision-making
Katalon also supports BDD testing with Cucumber, allowing you to import BDD feature files, create scripts with low-code features, link BDD steps to test scripts, and generate BDD-style reports.
To create a Cucumber feature file in Katalon Studio, go to File > New > BDD Feature File after installation.
Name your feature file. If you select the “Generate sample feature file template” option, Katalon will create a pre-written BDD script template in Gherkin, which you can then modify as needed.
Here is a simple Gherkin scenario as shown below:
Scenario: Login functionality
Given I navigate to the login page
When I enter my username
And I enter my password
And I click on the login button
Then I should be logged in successfully
At this point, you'll notice a yellow highlight on each step in the feature file. This indicates that the step definitions or test scripts haven't been created yet—essentially, the "glue code" that connects Cucumber and Katalon is missing. These small pieces of code are necessary to bridge the steps in your feature file with the actual test logic in Katalon.
The next step is to create the step definitions in the step file. To do this, navigate to Include > features > scripts > groovy > (default package) in the left sidebar. Right-click in this directory, select New > Step Definition, and create a Groovy script. This script will contain the code that maps each step in your feature file to its corresponding test logic.
As you can see, each of the BDD steps above have been linked with its corresponding test definition.
Next, you can use Katalon's fast test authoring features to convert the BDD feature file into a complete test script in seconds. Two key methods are:
- Built-in Keywords: Drag and drop pre-written code snippets to build the test case.
- Record-and-Playback: Record actions on your screen, capture object xPaths, and generate Selenium scripts for re-execution.
Katalon allows viewing and editing the full script, enabling you to finalize the step definitions. Once complete, click Run to execute the test and view the BDD test results in Katalon TestOps.
With Katalon, Cucumber’s capabilities are enhanced by:
- Low-code, fast test authoring
- Customizable coding options
- Cross-browser testing for broader coverage
- Easier script maintenance through centralized management
- Detailed BDD-style test results