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
- Better Collaboration: Cucumber uses plain language (Gherkin), making it easy for technical and non-technical team members to collaborate on feature files. This ensures all stakeholders align on the software’s expected behavior, reducing misunderstandings.
- Easier Communication with Non-Tech Stakeholders: Gherkin syntax reads like plain English, allowing non-technical stakeholders to understand, write, and review tests. This improves communication and reduces requirement errors.
- Supports Behavior-Driven Development (BDD): Cucumber promotes BDD, focusing on user behavior instead of technical details. This ensures the software is built to meet user needs and business goals.
- Readable and Maintainable Tests: Cucumber tests are easy to read and understand, making them more intuitive and easier to maintain. They are user-focused, reducing the need for extra documentation and helping new team members quickly grasp test cases.
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
FAQs On Cucumber Testing
1. What is the difference between Cucumber and Selenium?
Cucumber is a testing tool designed for Behavior-Driven Development (BDD), focusing on writing human-readable test scenarios in Gherkin. Selenium, on the other hand, is a browser automation tool used for functional testing. Cucumber can integrate with Selenium to automate the execution of BDD test cases in browsers.
2. Is Cucumber BDD or TDD?
Cucumber is a BDD (Behavior-Driven Development) tool. It bridges the communication gap between technical and non-technical stakeholders by allowing test cases to be written in plain language. TDD (Test-Driven Development) is a separate practice focusing on writing tests before the actual code, which is not Cucumber's primary purpose.
3. Is Gherkin a Cucumber?
No, Gherkin is not the same as Cucumber. Gherkin is the syntax used to write test scenarios in Cucumber. It al lows test cases to be written in a structured and human-readable format using keywords like Given, When, and Then.
4. Is Cucumber used for agile testing?
Yes, Cucumber is commonly used in Agile environments as it supports collaboration between developers, testers, and stakeholders. It aligns well with Agile principles by encouraging iterative development and clear communication through BDD.
5. Is JUnit a BDD or TDD tool?
JUnit is a TDD (Test-Driven Development) tool. It is primarily used to write and run unit tests for Java applications, supporting a TDD workflow. It is not designed for BDD like Cucumber.
6. Is TDD good for Agile?
Yes, TDD is a valuable practice in Agile development as it encourages writing testable code, ensures higher code quality, and supports quick iterations. TDD aligns well with Agile principles of delivering working software frequently.
7. Can you use both TDD and BDD?
Yes, TDD and BDD can be used together. TDD focuses on writing unit tests to guide code development, while BDD emphasizes collaboration and writing behavior-focused tests. Together, they ensure robust code and better alignment with business requirements.
8. Is TDD slower?
TDD can initially seem slower because of the time spent writing tests before code. However, it often speeds up development in the long run by reducing bugs, simplifying debugging, and ensuring that the code meets requirements early.