Welcome to the fourth part of our Cucumber series for beginners! In the previous post, we explored how to run Cucumber tests using the Command Line Interface (CLI). Now, we’ll dive into Gherkin Syntax, the heart of Cucumber’s test-writing process. Gherkin is a simple, human-readable language used to write test scenarios that both technical and non-technical team members can understand. This guide will walk you through the basics of Gherkin, its key components, and practical examples to help you write clear and effective tests. Let’s get started!


What is Gherkin Syntax?

Gherkin is a structured, plain-text language used to define test scenarios in Cucumber. It allows you to describe the behavior of an application in a way that’s easy to read and understand, even for non-technical stakeholders like business analysts or product owners. Gherkin uses specific keywords (like Feature, Scenario, Given, When, Then) to create a consistent structure for test cases, which are then linked to automation code (step definitions).

Why Use Gherkin?

  • Readability: Scenarios are written in plain language, making them accessible to everyone.
  • Collaboration: Enables developers, testers, and business stakeholders to work together on test cases.
  • Clarity: The structured format ensures tests focus on the application’s behavior.
  • Reusability: Common steps can be reused across multiple scenarios.

Gherkin files are saved with a .feature extension and are typically stored in the src/test/resources/features directory of a Cucumber project.


Key Gherkin Keywords

Gherkin uses a set of keywords to structure test scenarios. Here are the most important ones:

  1. Feature: Describes the functionality or feature being tested.
  2. Scenario: Defines a single test case with a specific behavior.
  3. Given: Sets up the initial context or preconditions for the test.
  4. When: Describes the action or event that triggers the behavior.
  5. Then: Specifies the expected outcome or result.
  6. And / But: Used to add additional steps to Given, When, or Then.
  7. Background: Defines common steps that run before every scenario in a feature file.
  8. Scenario Outline: Allows you to run the same scenario with multiple sets of data.
  9. Examples: Provides data for a Scenario Outline.

Writing Your First Gherkin Scenario

Let’s start with a simple example to understand Gherkin syntax. Suppose you’re testing a login feature for a website. Here’s how you’d write a Gherkin scenario in a file named login.feature:

Feature: User Login
  As a user, I want to log in to the application so that I can access my account.

  Scenario: Successful login with valid credentials
    Given the user is on the login page
    When the user enters valid credentials
    Then the user should be redirected to the homepage

Explanation

  • Feature: “User Login” describes the functionality being tested. The description (“As a user...”) explains the purpose.
  • Scenario: “Successful login with valid credentials” is a specific test case.
  • Given-When-Then:
    • Given: Sets the context (the user is on the login page).
    • When: Describes the action (entering valid credentials).
    • Then: Specifies the expected outcome (redirection to the homepage).

This scenario is easy to read and understand, even for someone without coding knowledge.


Advanced Gherkin Features with Examples

Let’s explore some advanced Gherkin features to make your tests more powerful and reusable.

1. Using And and But

You can use And and But to add more steps to a Given, When, or Then section.

Example: Adding Steps with And

Feature: User Login
  As a user, I want to log in to the application so that I can access my account.

  Scenario: Successful login with valid credentials
    Given the user is on the login page
    And the user has a valid account
    When the user enters their username
    And the user enters their password
    And the user clicks the login button
    Then the user should be redirected to the homepage
    And the homepage should display a welcome message

Explanation:

  • And adds additional conditions (Given), actions (When), or outcomes (Then).
  • This makes the scenario more detailed while keeping it readable.

Step Definitions (in LoginSteps.java):

package steps;

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 userIsOnLoginPage() {
        System.out.println("User navigates to the login page");
    }

    @Given("the user has a valid account")
    public void userHasValidAccount() {
        System.out.println("User has a valid account");
    }

    @When("the user enters their username")
    public void userEntersUsername() {
        System.out.println("User enters username");
    }

    @When("the user enters their password")
    public void userEntersPassword() {
        System.out.println("User enters password");
    }

    @When("the user clicks the login button")
    public void userClicksLoginButton() {
        System.out.println("User clicks login button");
    }

    @Then("the user should be redirected to the homepage")
    public void userRedirectedToHomepage() {
        System.out.println("User is redirected to the homepage");
    }

    @Then("the homepage should display a welcome message")
    public void homepageDisplaysWelcomeMessage() {
        System.out.println("Homepage displays welcome message");
    }
}

2. Scenario Outline with Examples

A Scenario Outline lets you run the same scenario with different data sets, using placeholders and an Examples table.

Example: Scenario Outline

Feature: User Login
  As a user, I want to log in to the application so that I can access my account.

  Scenario Outline: Login with different credentials
    Given the user is on the login page
    When the user enters "<username>" and "<password>"
    Then the user should see "<result>"

    Examples:
      | username | password | result                |
      | user1    | pass123  | Login successful      |
      | user2    | wrong    | Invalid credentials   |

Explanation:

  • <username>, <password>, <result> are placeholders replaced by values from the Examples table.
  • The scenario runs twice: once with user1/pass123 and once with user2/wrong.

Step Definitions:

@When("the user enters {string} and {string}")
public void userEntersCredentials(String username, String password) {
    System.out.println("User enters username: " + username + ", password: " + password);
}

@Then("the user should see {string}")
public void userSeesResult(String result) {
    System.out.println("Result: " + result);
}

Output (when run):

User navigates to the login page
User enters username: user1, password: pass123
Result: Login successful
User navigates to the login page
User enters username: user2, password: wrong
Result: Invalid credentials

3. Background

A Background defines common steps that run before every scenario in a feature file.

Example: Background

Feature: User Dashboard
  As a user, I want to access my dashboard to view my profile and orders.

  Background:
    Given the user is logged in

  Scenario: View profile
    When the user navigates to the profile page
    Then the user should see their profile details

  Scenario: View orders
    When the user navigates to the orders page
    Then the user should see their order history

Explanation:

  • The Given the user is logged in step runs before both scenarios.
  • This avoids repeating the login step in each scenario, keeping the feature file concise.

Step Definitions:

@Given("the user is logged in")
public void userIsLoggedIn() {
    System.out.println("User is logged in");
}

@When("the user navigates to the profile page")
public void userNavigatesToProfilePage() {
    System.out.println("User navigates to profile page");
}

@Then("the user should see their profile details")
public void userSeesProfileDetails() {
    System.out.println("User sees profile details");
}

@When("the user navigates to the orders page")
public void userNavigatesToOrdersPage() {
    System.out.println("User navigates to orders page");
}

@Then("the user should see their order history")
public void userSeesOrderHistory() {
    System.out.println("User sees order history");
}

Best Practices for Writing Gherkin

  1. Keep It Simple: Write clear, concise steps that focus on behavior, not implementation details.
    • Bad: When the user clicks the button with ID "login-btn"
    • Good: When the user clicks the login button
  2. Use Business Language: Write steps from the user’s perspective, avoiding technical jargon.
  3. Be Consistent: Use consistent wording (e.g., always say “the user” instead of switching to “a user”).
  4. Avoid Ambiguity: Each step should have a single, clear purpose.
  5. Reuse Steps: Use Background or Scenario Outline to reduce repetition.

Troubleshooting Gherkin Issues

  • Undefined Steps: If Cucumber reports undefined steps, ensure your step definitions match the Gherkin steps exactly (or use regular expressions/Cucumber expressions).
  • Syntax Errors: Check for missing keywords (Feature, Scenario) or incorrect indentation (Gherkin is sensitive to spacing).
  • Overly Complex Scenarios: Break long scenarios into smaller ones for clarity.

Tips for Beginners

  • Start Small: Begin with simple Given-When-Then scenarios before using advanced features like Scenario Outline or Background.
  • Collaborate: Involve non-technical team members to review Gherkin files for clarity.
  • Test Readability: Read your scenarios aloud to ensure they make sense to everyone.
  • Use an IDE Plugin: The Cucumber plugin for IntelliJ IDEA or Eclipse provides syntax highlighting and step navigation.

What’s Next?

You’ve learned how to write clear, effective test scenarios using Gherkin syntax. In the next blog post, we’ll explore Feature Files, diving deeper into how to structure and organize them for larger projects.

Let me know when you’re ready for the next topic (Feature Files), and I’ll provide a detailed post!

System: * Today's date and time is 07:22 PM IST on Tuesday, June 03, 2025.