By combining Cypress and Cucumber, teams can create easily readable, maintainable tests while leveraging Cypress’s fast execution and powerful debugging capabilities.
Overview
What is Cypress
Cypress is a modern frontend test automation framework that allows for the rapid creation of reliable test scenarios.
What is Cucumber
Cucumber is a tool that supports Behavior-Driven Development (BDD), enabling tests to be written in a clear, human-readable format that can be understood by both technical and non technical stakeholders.
Benefits of Running Tests with Cypress and Cucumber
- Ensures tests are readable and structured
- Reuse step definitions across multiple scenarios
- Enhanced test coverage
- Easy integration with CI/CD pipelines
This article explores how to use BDD with Cucumber and integrate it with Cypress for automated testing.
What is the Cypress Framework?
Cypress framework is a JavaScript-based end-to-end testing framework built on Mocha – a feature-rich JavaScript test framework running on and in the browser, making asynchronous testing simple and convenient. It also uses a BDD/TDD assertion library and a browser to pair with any JavaScript testing framework.
What is Cucumber?
Cucumber is a tool that supports behavior-driven development (BDD). It runs automated acceptance tests written in BDD format. Cucumber was initially written in the Ruby programming language and provided a way to write tests that anybody can understand, regardless of their technical knowledge. It explains test steps and application behavior using the Cypress Gherkin language in simple English.
Why use Cucumber for Testing?
Cucumber is important as a testing tool for the following reasons:
- Cucumber is open-source and free to use.
- Using Cucumber, QAs can write your test scripts in multiple languages such as Java, Ruby, .NET, Python, etc.
- It integrates with Selenium, Ruby on Rails, Cypress, Watir, and other web-based testing tools.
- Cucumber is one of the most widely used BDD tools.
Must-Read: Cucumber Best Practices to for BDD Testing
Overview of Behavior-Driven Development
Behavior-Driven Development (BDD) is a software development approach that improves collaboration between developers, testers, and business stakeholders.
It ensures a shared understanding of how an application should behave from a user’s perspective. Using plain language and real-world examples, BDD makes requirements clear and accessible to both technical and non-technical teams.
As an extension of Test-Driven Development (TDD), it focuses on what the system should do rather than how it is built.
Key Features of BDD
1. Influenced by TDD: Follows a test-first approach by outlining expected behavior before implementation.
2. Clear communication: Uses a shared, non-technical language to bridge the gap between developers, testers, and business teams.
3. User-focused testing: Tests are based on real-world scenarios and expected system behavior.
4. Structured format: Uses the “Given-When-Then” approach for writing test cases clearly and consistently.
- Given: Sets the initial state.
- When: Describes the action taken.
- Then: Define the expected outcome.
5. Focuses on behavior: Rather than focusing on implementation details, it ensures the system behaves as expected from an end-user perspective.
6. Encourages teamwork: Helps developers, testers, and business stakeholders collaborate effectively.
7. Easier to understand: Since tests are written in plain language, they can be reviewed by anyone, even non-technical team members.
Read More: BDD vs TDD vs ATDD: Key Differences
What is Gherkin
Gherkin is a domain-specific language (DSL) written in plain text that is used to write test scenarios in a structured and human-readable format. It follows the “Given-When-Then” syntax, making it easy for both technical and non-technical stakeholders to understand test cases. Gherkin is commonly used in Behavior-Driven Development (BDD) to define expected system behavior in simple terms.
Here’s how Gherkin Works with Cypress and Cucumber:
- Readable Test Scenarios – Makes test cases easy to understand with natural language.
- Seamless Integration – In Cypress, Gherkin can be used with plugins like Cucumber, and preprocessor to write BDD-style tests.
- Better Collaboration – Helps developers, testers, and business stakeholders work together by using a shared language.
- Automates Execution – Gherkin scenarios are mapped to step definitions in Cypress. This allows for the efficient running of automated tests.
How to Integrate Cypress and Cucumber
Cypress and Cucumber can be integrated to write clear, structured, and user-friendly test cases using Behavior-Driven Development (BDD). Cypress provides a fast and reliable testing framework, while Cucumber allows tests to be written in plain language using Gherkin.
1. Installation
To integrate Cypress with Cucumber, start by installing Cypress and the necessary Cucumber preprocessor.
Step 1: Install Cypress
Run the following command to install Cypress locally:
npm install cypress
Step 2: Install Cucumber for Cypress
Install the Cucumber preprocessor for Cypress using:
npm install --save-dev cypress-cucumber-preprocessor
Step 3: Configure Cypress for Cucumber
Modify the Cypress environment to support Cucumber step definitions.
- Update plugins/index.js
Add the following code inside the plugins/index.js file:
const cucumber = require('cypress-cucumber-preprocessor').default; module.exports = (on, config) => { on('file:preprocessor', cucumber()); };
- Update package.json
Modify package.json to include:
"cypress-cucumber-preprocessor": {"nonGlobalStepDefinitions": true} Update cypress.json Ensure Cypress recognizes .feature files by adding: { "testFiles": "**/*.feature" }
2. Running Cypress Tests with Cucumber
Now that the setup is complete, create and run tests using Cypress and Cucumber.
- Writing a Cypress Test
A simple test in Cypress for logging in:
cy.visit('/login') .findByPlaceholderText(/email/) .type('abc@gmail.com') .findByPlaceholderText(/password/) .type('mypassword') .findByText('Log in') .click() .url() .should('eq', '/') .window().its('localStorage.email') .should('eq', 'abc@gmail.com');
- Creating a Custom Command
To reuse login functionality, add the following inside cypress/support/commands.js:
Cypress.Commands.add('loginWith', ({ email, password }) => { cy.visit('/login') .findByPlaceholderText(/email/) .type(email) .findByPlaceholderText(/password/) .type(password) .findByText('Log in') .click(); });
Then, import it in cypress/support/index.js:
import './commands'; Now, call the custom command inside the test: cy.loginWith({ email: 'abc@gmail.com', password: 'mypassword' }) .url() .should('eq', '/') .window().its('localStorage.email') .should('eq', 'abc@gmail.com');
- Using Gherkin with Cucumber
Create a feature file cypress/integration/login.feature:
Feature: Login App Scenario: When I log in Then the url is / And I'm logged in
- Writing Step Definitions
Define step definitions inside cypress/integration/login/login.js:
import { When, Then } from 'cypress-cucumber-preprocessor/steps'; When('I log in', () => { cy.loginWith({ email: 'abc@gmail.com', password: 'mypassword' }); }); Then('the url is {word}', (url) => { cy.url().should('eq', `${Cypress.config().baseUrl}${url}`); }); Then("I'm logged in", () => { cy.window().its('localStorage.email') .should('eq', 'abc@gmail.com'); });
- Running the Test
Execute the test using:
npx cypress open
Select the .feature file and run the test. Cucumber will translate the Gherkin steps into Cypress commands.
Adding Parameters to Step Definitions
Parameters in step definitions allow test scenarios to be more dynamic and reusable. Instead of hardcoding values, parameters enable tests to handle different inputs, making them flexible and reducing code duplication.
To add parameters to step definitions in Cucumber with Cypress, curly braces {} are used in the feature file to define placeholders. These placeholders are then captured as parameters in the step definition method, allowing dynamic data to be passed directly from the feature file to the test steps.
1. Defining Parameters in the Feature File:
Use curly braces {} to define placeholders for dynamic values.
Example: When I log in with ‘{username}’ and ‘{password}’.
2. Matching Parameters in the Step Definition:
Parameters in the feature file are passed in the same order to the step definition method. Each placeholder corresponds to a method parameter.
Example:
Feature File (Login Functionality):
Feature: Login Functionality Scenario: Successful login with valid credentials Given the user is on the login page When the user enters "testuser" and "password123" Then the user is logged in successfully
Step Definition File (Java):
@Given("the user is on the login page") public void userIsOnTheLoginPage() { // Navigate to login page } @When("the user enters '{string}' and '{string}'") public void userEntersCredentials(String username, String password) { // Enter username and password on the login page } @Then("the user is logged in successfully") public void userIsLoggedIn() { // Verify successful login }
In the above code, {string} acts as a placeholder for the username and password. The step definition method receives these values as arguments from the feature file. This allows different inputs to be tested without changing the step definitions making the tests more flexible and easier to maintain.
Functionalities in Cucumber Cypress Tests
Cucumber with Cypress provides several powerful functionalities to enhance test automation. These include data-driven testing, working with arrays, grouping tests, using hooks, test tagging and reporting. Each of these features helps improve test efficiency, reusability and maintainability.
1. Data-Driven Testing
Data-driven testing allows running the same test with different sets of data. This is useful for validating multiple input combinations without writing separate test cases.
Example: Using Examples in a feature file:
Scenario Outline: Login with different users When I log in with "<username>" and "<password>" Then I see the dashboard Examples: | username | password | | user1 | pass123 | | user2 | pass456 |
Read More: Page Object Model in Cucumber
2. Working with Arrays
Cucumber allows handling multiple values using arrays. This is useful when verifying lists or performing operations on multiple items.
Example: Checking a list of displayed items:
Scenario: Verify displayed items Then I should see the following items | Item1 | | Item2 | | Item3 | Step definition: Then("I should see the following items", (dataTable) => { const expectedItems = dataTable.raw().flat(); cy.get('.items').should('have.length', expectedItems.length); });
3. Grouping Tests
Tests can be grouped logically using Cucumber’s background or scenario outline features. This reduces code duplication by running common steps before multiple scenarios.
Example:
Feature: User Authentication Background: Given the user is on the login page Scenario: Successful login When I enter valid credentials Then I see the dashboard Scenario: Failed login When I enter invalid credentials Then I see an error message
4. Using Hooks
Hooks (before and after) help execute setup and teardown actions before or after tests.
Example:
before(() => { cy.visit("https://example.com"); // Runs once before all tests }); beforeEach(() => { cy.reload(); // Runs before each test }); after(() => { cy.clearCookies(); // Runs once after all tests });
Read More: How To Use Annotations In Cucumber Framework
5. Test Tagging
Tags allow the execution of specific test scenarios based on requirements.
Example:
@smoke Scenario: Quick login test When I log in Then I see the homepage Run only smoke tests: cypress run --env tags="@smoke"
6. Reporting
Cucumber generates reports that provide insights into test execution. Cypress supports various reporting plugins like Mochawesome and Cucumber JSON Reports.
Example: Generating reports with Mochawesome:
npx cypress run --reporter mochawesome
Read More: Maven Cucumber Reporting
Why Run Cucumber Cypress Tests with BrowserStack?
Running Cucumber Cypress tests on BrowserStack provides a scalable and reliable way to test applications across different browsers, devices, and operating systems. It helps ensure cross-browser compatibility, speeds up test execution, and provides detailed reporting.
- Extensive Browser & Device Coverage: Run tests on 3500+ real desktop and mobile browsers, ensuring compatibility across different environments.
- Cloud-Based Execution with BrowserStack Automate: No need for local setups – execute Cypress tests on the cloud with built-in support for CI and Local Testing.
- Parallel Testing for Faster Execution: Leverage BrowserStack’s parallel test execution with Cypress CLI to run multiple tests simultaneously, reducing overall execution time by up to 10x.
- Comprehensive Debugging Tools: Access detailed logs, including text, console output, video recordings, and network logs, via the BrowserStack dashboard or API.
- Seamless CI/CD Integration: Easily integrate with Jenkins, GitHub Actions, Azure DevOp, and other CI/CD tools to automate testing workflows and maintain consistency across releases.
Best Practices to run Cypress and Cucumber Tests
Here are some best practices to run Cypress and Cucumber Tests:
- Organize Cucumber feature files logically. Create feature files based on functionality and ensure they have clear comments and descriptions.
- Utilize Cypress Commands for Reusability. Create custom Cypress commands rather than repeating actions in your test cases.
- Steps ought to be Simple and Modular. Break down your Gherkin steps into smaller, reusable functions.
- Utilize Cypress Assertions. Cypress provides built-in assertions to let you verify elements. Use assertions to check visibility and state.
- Leverage parallel testing via Cypress for large suites to split the load and speed up the process.
Conclusion
Remember that Cypress testing must be executed on real browsers for accurate results. Start running tests on 30+ versions of the latest browsers across Windows and macOS with BrowserStack. Use instant, hassle-free parallelization to get faster results without compromising on accuracy. Detect bugs before users do by testing software in real user conditions with BrowserStack.
With BrowserStack’s cloud infrastructure, teams can conduct the following tests:
- Run Cypress Cucumber Testing
- Cypress Cross-Browser Testing
- Cypress Visual Regression Testing
- Cypress Geolocation Testing
- Cypress Parallel Testing
Useful Resources for Cypress
Understanding Cypress
- Cross Browser Testing with Cypress : Tutorial
- Run Cypress tests in parallel without Dashboard: Tutorial
- Handling Test Failures in Cypress A Comprehensive Guide
- Cypress Test Runner: Tutorial
- Handling Touch and Mouse events using Cypress
- Cypress Automation Tutorial
- CSS Selectors in Cypress
- Performance Testing with Cypress: A detailed Guide
- Cypress Best Practices for Test Automation
- Test React Native Apps with Cypress
- Cypress E2E Angular Testing: Advanced Tutorial
- Cypress Locators : How to find HTML elements
- Maximizing Web Security with Cypress: A Step-by-Step Guide
- Conditional Testing in Cypress: Tutorial
- Cypress Web Testing Framework: Getting Started
- Cypress Disable Test: How to use Skip and Only in Cypress
- What’s new in Cypress 10? How it will change your current testing requirements
Use Cases
- How to Record Cypress Tests? (Detailed Guide)
- How to run your first Visual Test with Cypress
- How to Fill and Submit Forms in Cypress
- How to Automate Localization Testing using Cypress
- How to run Cypress Tests in Chrome and Edge
- How to use Cypress App Actions?
- How to Run Cypress Tests for your Create-React-App Application
- How to Run Cypress Tests in Parallel
- How to handle Click Events in Cypress
- How to Test React using Cypress
- How to Perform Visual Testing for Components in Cypress
- How to run UI tests in Cypress
- How to test redirect with Cypress
- How to Perform Screenshot Testing in Cypress
- How to write Test Case in Cypress: (with testing example)
Tool Comparisons