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 theExamples
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
).
- Feature File:
Updatesearch.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
- Create a Custom Parameter Type:
CreateParameterTypes.java
insrc/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("$", ""));
}
}
- Update Step Definitions:
Add toSearchSteps.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 aDouble
by removing the$
symbol. - The step definitions use
{currency}
to capture the price as aDouble
.
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
- Use Built-in Types: Leverage
{string}
,{int}
,{float}
for simplicity. - Keep Expressions Clear: Avoid overly complex patterns; use custom parameter types if needed.
- Match Scenario Text: Ensure the expression matches the Gherkin step exactly, including quotes for
{string}
. - Test Expressions: Run scenarios to verify that parameters are captured correctly.
- 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.