Welcome to the thirteenth part of our Cucumber series for beginners! In the previous post, we explored Scenario Hooks, which manage setup and teardown tasks for tests. Now, we’ll dive into Cucumber Expressions, a feature in Cucumber that provides a simple and intuitive way to match Gherkin steps with step definitions using parameters. This guide will explain what Cucumber Expressions are, how to use them, and provide practical examples to make it easy for beginners and valuable for experienced professionals. Let’s get started!


What are Cucumber Expressions?

Cucumber Expressions are a syntax used in Cucumber step definitions to match Gherkin steps and capture parameters (e.g., strings, numbers) from those steps. Introduced as a simpler alternative to regular expressions, Cucumber Expressions allow you to define flexible step definitions that can handle dynamic values in your scenarios, such as usernames, quantities, or dates.

Why Use Cucumber Expressions?

  • Simplicity: Easier to read and write compared to regular expressions.
  • Built-in Parameter Types: Support common data types like {string}, {int}, and {float} out of the box.
  • Flexibility: Match a wide range of step variations without complex regex patterns.
  • Maintainability: Clearer syntax makes step definitions easier to maintain.

How Cucumber Expressions Work

In a step definition, Cucumber Expressions are used in annotations (e.g., @Given, @When, @Then) to match the text of a Gherkin step. Placeholders like {string}, {int}, or {word} capture values from the step, which are then passed as parameters to the method.

Basic Syntax

Scenario: Some scenario
  Given the user enters "John" in the form
@Given("the user enters {string} in the form")
public void userEntersName(String name) {
    System.out.println("Name entered: " + name);
}

The {string} placeholder matches the value "John" and passes it to the name parameter.

Built-in Parameter Types

Cucumber Expressions support several built-in parameter types:

  • {string}: Matches a quoted string (e.g., "John", "123").
  • {word}: Matches a single word without spaces (e.g., John, pass123).
  • {int}: Matches an integer (e.g., 42, -10).
  • {float}: Matches a floating-point number (e.g., 3.14, -0.5).
  • {}: Matches any value (generic placeholder).
  • {biginteger}: Matches a large integer (e.g., 123456789012345).
  • {double}: Matches a double-precision number (e.g., 3.14159).

Using Cucumber Expressions in a Feature File

Let’s create a feature file for a product search scenario that uses Cucumber Expressions to handle dynamic search terms and quantities. Assume you have a Cucumber project set up with Java and Maven, as described in the Installation and Setup post.

Example: Product Search with Cucumber Expressions

Create a file named search.feature in src/test/resources/features:

Feature: Product Search
  As a user, I want to search for products so that I can find items to purchase.

  Scenario: Search for a product with a specific quantity
    Given the user is on the search page
    When the user searches for "laptop" with quantity 2
    Then the user should see 2 laptops in the results

Step Definitions

Create SearchSteps.java in src/test/java/steps:

package steps;

import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;

public class SearchSteps {
    @Given("the user is on the search page")
    public void userIsOnSearchPage() {
        System.out.println("Navigating to the search page");
        // Placeholder: Add Selenium code
    }

    @When("the user searches for {string} with quantity {int}")
    public void userSearchesForProduct(String product, int quantity) {
        System.out.println("Searching for: " + product + ", Quantity: " + quantity);
        // Placeholder: Add Selenium code
    }

    @Then("the user should see {int} laptops in the results")
    public void userSeesResults(int quantity) {
        System.out.println("Verifying " + quantity + " laptops in results");
        // Placeholder: Add Selenium code
    }
}

Explanation:

  • {string}: Captures the product name ("laptop") as a string.
  • {int}: Captures the quantity (2) as an integer.
  • The captured values are passed as parameters to the step definition methods.

Run the Scenario

Use the TestRunner class or Cucumber CLI:

mvn test

Output:

Navigating to the search page
Searching for: laptop, Quantity: 2
Verifying 2 laptops in results

1 Scenarios (1 passed)
3 Steps (3 passed)
0m0.123s

Using Cucumber Expressions with Scenario Outlines

Cucumber Expressions work seamlessly with Scenario Outlines to handle dynamic data across multiple test cases.

Example: Scenario Outline with Cucumber Expressions

Update search.feature:

Feature: Product Search
  As a user, I want to search for products so that I can find items to purchase.

  Scenario Outline: Search for products with different quantities
    Given the user is on the search page
    When the user searches for "<product>" with quantity <quantity>
    Then the user should see <quantity> <product>s in the results

    Examples:
      | product   | quantity |
      | laptop    | 2        |
      | phone     | 3        |
      | tablet    | 1        |

Update Step Definitions:
The existing SearchSteps.java already handles the dynamic values with {string} and {int}:

@When("the user searches for {string} with quantity {int}")
public void userSearchesForProduct(String product, int quantity) {
    System.out.println("Searching for: " + product + ", Quantity: " + quantity);
}

@Then("the user should see {int} {string}s in the results")
public void userSeesResults(int quantity, String product) {
    System.out.println("Verifying " + quantity + " " + product + "s in results");
}

Output (when run):

Navigating to the search page
Searching for: laptop, Quantity: 2
Verifying 2 laptops in results

Navigating to the search page
Searching for: phone, Quantity: 3
Verifying 3 phones in results

Navigating to the search page
Searching for: tablet, Quantity: 1
Verifying 1 tablets in results

3 Scenarios (3 passed)
9 Steps (9 passed)
0m0.367s

Explanation:

  • The {string} and {int} placeholders match the <product> and <quantity> values from the Examples table.
  • The step definitions handle the dynamic inputs without needing changes.

Custom Parameter Types

While built-in parameter types like {string} and {int} cover most cases, you can define custom parameter types to handle specific formats (e.g., dates, currencies). This requires creating a custom type in a configuration class.

Example: Custom Parameter Type for Currency

Let’s create a custom parameter type for a currency amount (e.g., $10.99).

  1. Feature File:
    Update search.feature:
Feature: Product Search
  As a user, I want to search for products so that I can find items to purchase.

  Scenario: Search for a product with a price filter
    Given the user is on the search page
    When the user searches for "laptop" with price $99.99
    Then the user should see laptops priced at $99.99
  1. Create a Custom Parameter Type:
    Create ParameterTypes.java in src/test/java/steps:
package steps;

import io.cucumber.java.ParameterType;

public class ParameterTypes {
    @ParameterType("\\$[0-9]+\\.[0-9]{2}")
    public Double currency(String value) {
        return Double.parseDouble(value.replace("$", ""));
    }
}
  1. Update Step Definitions:
    Add to SearchSteps.java:
@When("the user searches for {string} with price {currency}")
public void userSearchesForProductWithPrice(String product, Double price) {
    System.out.println("Searching for: " + product + ", Price: $" + price);
}

@Then("the user should see {string}s priced at {currency}")
public void userSeesResultsWithPrice(String product, Double price) {
    System.out.println("Verifying " + product + "s priced at $" + price);
}

Explanation:

  • @ParameterType: Defines a custom parameter type named currency that matches a dollar amount (e.g., $99.99) using a regular expression.
  • Conversion: The currency method converts the matched string to a Double by removing the $ symbol.
  • The step definitions use {currency} to capture the price as a Double.

Output (when run):

Navigating to the search page
Searching for: laptop, Price: $99.99
Verifying laptops priced at $99.99

1 Scenarios (1 passed)
3 Steps (3 passed)
0m0.123s

Cucumber Expressions vs. Regular Expressions

Cucumber Expressions are designed to be simpler than regular expressions (regex), but both can be used in step definitions. Here’s a quick comparison:

Aspect Cucumber Expressions Regular Expressions
Syntax Simple, e.g., {string}, {int} Complex, e.g., ([a-zA-Z]+), (\d+)
Readability Easy to read and write Harder to read, especially for beginners
Built-in Types Supports {string}, {int}, etc. Requires manual regex for types
Flexibility Less flexible for complex patterns Highly flexible for any pattern
Use Case Most common scenarios Advanced matching or legacy projects

Example:

  • Cucumber Expression: the user enters {string}
  • Regular Expression: the user enters "([^"]*)"

We’ll cover regular expressions in the next post.


Best Practices for Cucumber Expressions

  1. Use Built-in Types: Leverage {string}, {int}, {float} for simplicity.
  2. Keep Expressions Clear: Avoid overly complex patterns; use custom parameter types if needed.
  3. Match Scenario Text: Ensure the expression matches the Gherkin step exactly, including quotes for {string}.
  4. Test Expressions: Run scenarios to verify that parameters are captured correctly.
  5. Document Custom Types: Comment custom parameter types for team understanding.

Troubleshooting Cucumber Expression Issues

  • Parameter Mismatch: Ensure the step text matches the expression (e.g., {string} requires quotes in the Gherkin step).
  • Undefined Steps: If a step is undefined, check that the Cucumber Expression matches the step text.
  • Custom Type Errors: Verify the regular expression in @ParameterType is correct and the conversion logic works.
  • Case Sensitivity: Cucumber Expressions are case-sensitive; ensure consistency.

Tips for Beginners

  • Start with {string} and {int}: These cover most use cases for beginners.
  • Run Tests Frequently: Test step definitions to catch expression errors early.
  • Use Snippets: Run a feature file with undefined steps to generate Cucumber Expression snippets.
  • Avoid Overcomplicating: Stick to built-in types unless a custom type is necessary.

What’s Next?

You’ve learned how to use Cucumber Expressions to create flexible step definitions that handle dynamic data. In the next blog post, we’ll explore Regular Expressions, which offer more advanced pattern matching for complex step definitions.

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

System: * Today's date and time is 04:32 PM IST on Friday, June 06, 2025.