Writing Feature Files in Cucumber BDD – A Detailed Guide

Feature files in Cucumber BDD are written in Gherkin syntax and define test scenarios in a human-readable format. They are essential for behavior-driven development (BDD) and help bridge the gap between business analysts, testers, and developers.


1️⃣ What is a Feature File in Cucumber?

A Feature File is a .feature file that contains the high-level description of a software feature. It describes multiple test scenarios using the Gherkin language.

Basic Structure of a Feature File

Feature: Login functionality
  As a registered user
  I want to log into the application
  So that I can access my account dashboard

πŸ”Ή Breakdown:

  • Feature: Describes the feature under test.
  • As a user: Specifies the role.
  • I want: Describes the desired action.
  • So that: Explains the benefit or goal.

πŸ“Œ File Location:
src/test/resources/features/Login.feature


2️⃣ Writing Test Scenarios in Cucumber

A Scenario represents one specific test case inside a feature file.

Example: Writing a Simple Scenario

Feature: Login functionality

Scenario: Successful login with valid credentials
  Given The user is on the login page
  When The user enters valid username "testUser"
  And The user enters password "password123"
  And The user clicks on the login button
  Then The user should be redirected to the dashboard

πŸ”Ή Key Components of Gherkin:

  • Given: Defines the precondition (e.g., opening the login page).
  • When: Describes actions taken by the user.
  • And: Connects multiple actions.
  • Then: Specifies the expected outcome.

3️⃣ Using Scenario Outline with Examples

A Scenario Outline allows running the same test multiple times with different data sets.

Example: Login with Different Users

Scenario Outline: Login with multiple users
  Given The user is on the login page
  When The user enters "<username>" and "<password>"
  And The user clicks on the login button
  Then The user should see "<message>"

Examples:
  | username  | password   | message                  |
  | user1     | pass123    | Welcome user1!          |
  | user2     | pass456    | Welcome user2!          |
  | invalid   | wrongPass  | Invalid credentials!    |

πŸ”Ή How it Works?

  • <username>, <password>, and <message> are placeholders.
  • Cucumber replaces them with values from the Examples table.
  • The scenario runs 3 times, once for each row.

πŸ“Œ Benefit: Reduces code duplication by reusing the same scenario.


4️⃣ Using Background to Reduce Duplication

A Background section runs before every scenario, preventing repetition of common preconditions.

Example: Background for Precondition

Feature: Login functionality

Background:
  Given The user is on the login page

Scenario: Successful login
  When The user enters "validUser" and "validPass"
  And The user clicks on the login button
  Then The user should see "Welcome validUser!"

Scenario: Failed login attempt
  When The user enters "invalidUser" and "wrongPass"
  And The user clicks on the login button
  Then The user should see "Invalid credentials!"

πŸ”Ή Key Benefit:

  • The Background step runs before every scenario.
  • Avoids repetition of "Given The user is on the login page".

5️⃣ Writing Step Definitions in Java

Each Gherkin step must be linked to a Java method in a Step Definition file.

πŸ“Œ File Location:
src/test/java/stepDefinitions/LoginSteps.java

Example: Java Step Definitions

package stepDefinitions;

import io.cucumber.java.en.*;

public class LoginSteps {
    
    @Given("The user is on the login page")
    public void user_is_on_login_page() {
        System.out.println("User navigates to login page");
    }

    @When("The user enters {string} and {string}")
    public void user_enters_credentials(String username, String password) {
        System.out.println("Entering Username: " + username);
        System.out.println("Entering Password: " + password);
    }

    @When("The user clicks on the login button")
    public void user_clicks_login_button() {
        System.out.println("Clicking login button");
    }

    @Then("The user should see {string}")
    public void user_sees_message(String message) {
        System.out.println("Expected Message: " + message);
    }
}

πŸ”Ή How it Works?

  • {string} matches placeholders in feature files.
  • Values from the Examples table are passed as parameters.

6️⃣ Running the Cucumber Tests

To execute Cucumber tests, we use a Runner Class.

πŸ“Œ File Location:
src/test/java/runners/TestRunner.java

Example: Cucumber Test Runner

package runners;

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 = "stepDefinitions",
        plugin = {"pretty", "html:target/cucumber-reports.html"},
        monochrome = true
)
public class TestRunner {
}

πŸ”Ή Annotations Explained:

  • @RunWith(Cucumber.class) → Runs the tests using Cucumber.
  • @CucumberOptions
    • features → Path to .feature files.
    • glue → Package containing step definitions.
    • plugin → Generates reports.
    • monochrome = true → Improves console readability.

✅ Summary

Concept Description
Feature File Defines the overall feature and test cases
Scenario Represents a single test case
Scenario Outline Runs the test multiple times with different data
Examples Table Provides test data for Scenario Outline
Background Runs common preconditions before each scenario
Step Definitions Maps Gherkin steps to Java methods
Test Runner Executes the Cucumber tests

πŸ“Œ Key Takeaways

  1. Use Scenario Outline and Examples to avoid redundant test cases.
  2. Leverage Background for common setup steps.
  3. Write clean Step Definitions to map feature steps to Java code.
  4. Use CucumberOptions in the Test Runner for better reporting.
  5. Follow BDD best practices for maintainability.

Would you like me to add more advanced concepts like DataTables, Hooks, Parallel Execution, or Cucumber with Selenium? πŸš€