User API
Automated Testing Cypress & Cucumber BDD

Cypress & Cucumber BDD: A Dynamic Duo for Enhancing Your QA Automation Strategy

Recently, Cypress has become a popular tool for testing the front end of websites because it has strong features and is easy to use. When Cypress is combined with a Behavior-Driven Development (BDD) framework, it makes testing even better. This approach helps teams work together more smoothly, makes testing quicker, and ensures that more parts of the application are tested thoroughly. This combination helps make sure that the testing process meets business needs and user expectations effectively.

In this blog post, we will dive into why Cypress is a primary choice for BDD, how to set up Cypress for BDD in your projects, and best practices for writing and maintaining your tests. We’ll also share some practical examples to help you get started and demonstrate the real-world impact of integrating these two powerful tools. So, buckle up and prepare to take your testing to the next level with Cypress and BDD!

Table of Contents

Introduction to Cypress and Cucumber BDD

Cypress emerges as a powerful tool for developers and testers aiming to create robust and reliable web applications. BDD is a collaborative development approach that focuses on the “what” rather than the “how” of testing.  It allows teams to write test cases in a natural, human-readable language called Gherkin. Cucumber empowers Behavior-Driven Development (BDD) by providing tools to write clear and collaborative tests.In this blog, we will explore how Behavior-Driven Development (BDD) can be seamlessly integrated with Cypress to enhance the clarity and efficiency of your testing processes.
You can learn more about Cypress and BDD framework by exploring these insightful blog posts by Jignect: Cypress Web UI blog, BDD Framework Blog.

Why Integrate Cypress with Cucumber BDD?

Below are the key points describing why integrating Cypress with Cucumber BDD is advantageous for enhancing your testing process:

  • Improved Collaboration:  Cucumber BDD uses Gherkin, a plain-text language, to describe test scenarios. This makes tests understandable to both technical and non-technical stakeholders, promoting better communication and collaboration between developers, testers, and business analysts.
  • Enhanced Readability and Maintainability: Combining Cucumber’s step definitions with Cypress’s test automation features allows you to build a strong testing framework that is simpler to maintain and update over time. This is particularly important in agile development environments where faster iteration and testing are crucial.
  • Code Reuse and Parameterization: Cucumber’s Given-When-Then structure allows for easy reuse of common steps across multiple test scenarios. Additionally, the ability to run the same test scenario with different sets of data in feature files saves time and effort for the testing team.
  • Behaviour-Driven Approach: Cucumber’s BDD approach focuses on describing the application’s behaviour from the user’s perspective, which aligns well with Cypress’s end-to-end testing capabilities. This helps ensure that the application is tested based on its actual usage.
  • Early Detection of Requirement Misunderstandings: Because BDD focuses on defining behaviours before development begins, it allows for early identification of any misunderstandings in the requirements. Detecting these issues early in the development cycle can help reduce the time and cost associated with fixing problems post-development.
  • TDD (Test Driven Development) Compatibility:  Cypress integrated with Cucumber BDD supports a TDD approach where tests are written before the code itself. This not only ensures that the code meets the predefined specifications but also leads to a more structured and disciplined development process.
  • Reusability: By integrating Cypress with Cucumber BDD, you can write reusable step definitions that can be used in multiple tests, reducing duplication and improving maintainability.

Prerequisite Steps for Setting up Cypress with BDD Framework

In this blog, we’ve utilized the following versions of the respective libraries and applications for practical implementation:

  1. Cypress version: 13.8.1
  2. Cypress-cucumber-preprocessor: 4.3.1
  3. Node JS version: v20.12.2
  4. Visual Studio Code version: 1.88.1
  • Install Node JS
    • First, download Node.js from its official website and install it on your system.
  • Download & Install Visual Studio Code

1️⃣ Install and Launch Cypress

  • Open Visual Studio Code and launch the integrated terminal.
  • To create a package.json file, typenpm init” in the terminal. You can either follow the on-screen prompts or simply press Enter to skip through.
npm-initialization
  • Next, install Cypress by typing “npm install cypress –save-dev” and pressing Enter.
cypress-install
  • In the terminal, type “npx cypress open” and press Enter. This will open Cypress in headed mode.
cypress-open
  • Select ‘E2E Testing’, and click “Continue” on the Configuration files screen.

Congratulations! Your Cypress project is set up and ready for you to start your first test.

2️⃣ Add BDD plugin

To add a BDD plugin to Cypress, choose a BDD plugin compatible with Cypress, such as ‘Cypress-Cucumber-Preprocessor’, which allows you to use Cucumber BDD syntax directly within Cypress. 

To install the plugin, execute the below command in your terminal:

install-cyress-cucumber

3️⃣ Configure Cypress

Add the below code to your cypress.config.js file:

const { defineConfig } = require("cypress");
const cucumber = require('cypress-cucumber-preprocessor').default;

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('file:preprocessor', cucumber())
    },
    specPattern: "cypress/Feature/*.feature",
  },
});

Add below code in your package.json file:

 "cypress-cucumber-preprocessor": {
    "nonGlobalStepDefinitions": true,
    "stepDefinitions": "cypress/stepDefinitions"
  },
    "testFiles": "**/*.feature"

When you set ‘nonGlobalStepDefinitions’ to ‘true’ in your package.json, it changes this default behaviour. Instead of having a global directory for all step definitions, each feature file will look for a corresponding directory with the same name as the feature file to find its step definitions. This directory should be in the same folder as the feature file or in a nested structure under a specific folder named after the feature file.

Add the below code into your support>e2e.js file:

Cypress.on('uncaught:exception', (err, runnable) => {
    // Return false to prevent the test from failing
    return false;
});

 This code is designed to prevent your test case from failing because of uncaught exceptions in Cypress. It configures Cypress to overlook any uncaught JavaScript exceptions.

Writing BDD tests in Cypress

1️⃣ Define Feature Files:

Feature files are where you define your test scenarios using Gherkin syntax. This file is used to describe the behavior of the application in a language that can be understood by all stakeholders

Create a new folder ‘Feature’ inside the cypress directory and create a new file ‘QaBlogs.feature’.

feature-file-1

Write the below code into your QaBlogs.feature file

Feature: Navigation and validation of the QA Blogs page on the Jignect website

    Background:
        Given I am on the Jignect homepage
    Scenario: Navigate to the QA Blogs page and verify the header
        When I click on the "QA Blogs" button
        Then I should be redirected to the QA Blogs page
        And the page header should say "QA Blogs"

Explanation of the Gherkin Feature File:

  • Feature: The ‘Feature’ keyword provides a high-level description of a software feature. . It acts as a starting point for describing a specific functionality of the application being tested. and is used to group related scenarios.
  • Background: The ‘Background’ section is used for steps that are common to all the scenarios in the feature file. In this case, it’s navigating to the Jignect homepage before each scenario.
  • Scenario: This describes a specific scenario under which a feature is tested. It consists of a series of steps.
  • Given, When, Then, And: These are the steps used to describe the scenario. ‘Given’ is used to set up the initial context or preconditions for a test scenario, ‘When’ describes an action, and ‘Then’ is used to describe the outcome or assertion that should follow the action. ‘And’ is used to continue any of the Given, When, or Then steps.

2️⃣ Implement Step Definitions:

Step definition files are where the Gherkin steps in the feature files are translated into executable code. Each step in a Gherkin file is mapped to a function in a step definition file that executes code when that step is run.

Create a new folder ‘stepDefinitions’ inside the cypress directory and create a new file ‘QaBlogs.cy.js’

stepdefinition-file-1

Write the below code into your QaBlogs.cy.js file:

import { Given, When, Then, And } from "cypress-cucumber-preprocessor/steps"
import HomePage from '../PageObject/HomePage';
import QaBlogs from '../PageObject/QaBlogs';

const homePage = new HomePage();
const qaBlogs = new QaBlogs();

Given('I am on the Jignect homepage', () => {
    homePage.visit();
});

When('I click on the {string} button', (linkText) => {
    homePage.clickOnHeaderLink(linkText);
});

Then('I should be redirected to the QA Blogs page', () => {
    cy.url().should('include', '/qa-blog')
});

And('the page header should say {string}', (qaBlogsHeader) => {
    qaBlogs.getHeaderText().should('have.text', qaBlogsHeader);
});

3️⃣Create Page Object Files:

Page object files are used to apply the Page Object Model design pattern, which encourages better maintenance and reusability of the code. Each page object file typically represents a page in the application, including the elements of the page and the interactions with them. 

Create a new folder ‘PageObject’ inside the cypress directory and create 2 new files: ‘HomePagejs’, ‘QaBlogs.js’

pageObjects

Write the below code into your HomePage.js file:

const headerLink = (linkText) => `.navigator ul#menu-main-menu li a:contains('${linkText}')`;

class HomePage {
    visit() {
        cy.visit('https://jignect.tech/');
    }
    clickOnHeaderLink(linkText) {
        cy.get(headerLink(linkText)).click();
    }
}
export default HomePage;

Write the below code into your QaBlogs.js file:

const headerText = `h1[class='page-title-inner']`;

class QaBlogs {

    getHeaderText() {
        return cy.get(headerText);
    }
}
export default QaBlogs;

Link Your Feature file and Step Definition file:

  • Install below extensions in VS Code:
Extensions
  • Create a new folder ‘.vscode’ inside the root folder i.e CypressTest.
  • Create a new file ‘settings.json’ inside your .vscode folder.
json-data-file
  • Write the below code in your ‘settings.json’ file.
json

Now navigate to your Feature file > Right-click on any step > Click on ‘Go to Definition’ and you should be redirected to the step definition file for the respective step.

Executing BDD tests in Cypress

Run Cypress tests

  • Run this command in your VS Code terminal: npx cypress open
cypress-run-1
  • Click on ‘E2E Testing’ > Choose ‘Chrome’ browser > Choose the feature file ‘QaBlogs.feature’ and click on it.
cypress-dashboard-1

Now, You should now see your Cypress test executing successfully in the Cypress Runner.

View Test results

Cypress Test Runner: The results will be displayed directly in the interface. You’ll see which scenarios passed or failed along with detailed step results.

result-analysis-1

Command Line: Results will be output to the terminal. For more detailed reports, you might want to set up a reporting tool like Allure report or Mochawesome.

To see the Test Results in Terminal, run the cypress test in Headless mode by executing this command:

Npx cypress run -b chrome

cypress-run-with-specific-browser

And There it is! Your test results will be displayed in the terminal.

cypress-result-1

Best Practices for Cypress and BDD Integration

Write Reusable Step Definitions: Write step definitions that are generic so they can be reused across different feature files. This reduces duplication and eases maintenance. For example, Use parameters in your step definitions to make them applicable to a variety of scenarios.

Example:

In the feature file which we have explained in this blog, we have the below step in the ‘QaBlogs.feature’ file:

When I click on the "QA Blogs" button
And the page header should say "QA Blogs

In the Step definition file ‘QaBlogs.cy.js’ the implementation will be like this:

import { When } from "cypress-cucumber-preprocessor/steps"

When('I click on the {string} button', (linkText) => {
    homePage.clickOnHeaderLink(linkText);
});

And('the page header should say {string}', (qaBlogsHeader) => {
    qaBlogs.getHeaderText().should('have.text', qaBlogsHeader);
});

Here you can notice how this step uses the parameters ‘linkText’ and ‘qaBlogsHeader’, making them reusable for different link navigation scenarios with varying links and header texts. Changes to the navigation link only require modifications in the step definitions, keeping the feature files focused on user stories.

Keep Tests Atomic: Write tests that are atomic, meaning each test should focus on testing a single piece of functionality or behaviour. In Behavior-Driven Development (BDD), where tests are written in natural language (Gherkin syntax in Cucumber), clarity is key. Atomic tests align well with this requirement because they address only one behaviour or user story at a time, making it easier for developers, testers, and stakeholders to understand the purpose and scope of each test.

Organize Feature Files Logically: Structure your feature files and scenarios in a way that reflects the user journey or feature sets of the application. Each feature file should have a name that clearly describes what part of the application it tests. For larger sections of the application, consider using subdirectories to organize feature files further.

Utilize Page Object Model: In a BDD framework with Cypress, Gherkin scenarios are translated into step definitions. Utilize page objects within these step definitions to interact with the application. This approach maintains a clear separation between test scenarios and automation logic. Each page object should represent a specific part of your application, usually mirroring a single page or a major component of the UI. The page object should include all the behaviours, elements, and methods related to that page, ensuring that any interaction with it goes through its corresponding page object.

Review and Refactor Regularly: As the application evolves, so should the organization of your feature files. Regular reviews of the file structure are important to ensure they continue to match the application’s structure and business requirements. Refactoring might be necessary when new features are added or existing features are significantly changed. By continually improving the test code, you prevent the build-up of outdated or inefficient coding that, if ignored, makes future changes more difficult and time-consuming.

Conclusion

Integrating Cucumber with Cypress offers a robust solution for implementing Behavior-Driven Development (BDD) in web testing environments. This integration combines the robust browser automation and network stubbing capabilities of Cypress with the versatile, language-agnostic BDD framework of Cucumber, enabling teams to define software behaviours in simple, human-readable language. Cypress with Cucumber facilitates easy setup and quicker execution of tests, reducing the time and effort required for end-to-end test automation. The use of Gherkin syntax to write test cases not only clarifies the testing objectives but also facilitates better communication between developers, testers, and non-technical stakeholders, ensuring that all parties have a clear understanding of the project requirements and functionalities. However, the Integration of Cypress and Cucumber BDD isn’t without limitations. Teams new to either Cypress or Cucumber might face a sharp learning curve as they adapt to both tools’ specifics, including Gherkin syntax and the JavaScript-based environment of Cypress. Although Cypress is known for its fast execution of tests, integrating it with Cucumber might introduce a slight delay due to the overload of reading Gherkin files and mapping them to executable code. Cucumber tests can become a maintenance burden if they’re written to target specific UI elements or implementation details. Even minor changes in UI or how the application works can break numerous scenarios. This forces you to update the tests constantly, even though the core functionality remains unchanged.

In Conclusion, the decision to integrate Cypress with Cucumber depends on your specific project needs and team expertise. If clear communication, collaboration, and readable tests are priorities, the benefits outweigh the drawbacks.


Keep practicing and exploring to master these powerful tools further with Jignect

Witness how our meticulous approach and cutting-edge solutions elevated quality and performance to new heights. Begin your journey into the world of software testing excellence. To know more refer to Tools & Technologies & QA Services.

If you would like to learn more about the awesome services we provide, be sure to reach out.

Happy testing! 🙂