Chapter 2: Cucumber BDD Framework
Step definitions are the bridge between English and Java. Understanding how to write flexible, reusable step definitions is the difference between a fragile framework and a robust one. Let us go deeper.
Cucumber Expressions are simpler than regex. They use curly braces to capture parameters:
// {string} — captures a quoted string
@When("the user enters username {string}")
public void enterUsername(String username) { }
// Matches: the user enters username "testuser"
// {int} — captures a whole number
@Then("the cart should contain {int} items")
public void cartContains(int count) { }
// Matches: the cart should contain 5 items
// {double} — captures a decimal number
@Then("the total should be {double}")
public void totalIs(double amount) { }
// Matches: the total should be 99.99
// {word} — captures a single word (no quotes)
@When("the user clicks the {word} button")
public void clickButton(String buttonName) { }
// Matches: the user clicks the login button
// Matches: the user clicks the submit button| Expression | Matches | Java Type |
|---|---|---|
| {string} | Quoted text ("hello" or 'hello') | String |
| {int} | Integer (42, -5) | int |
| {double} | Decimal (3.14, 99.99) | double |
| {float} | Decimal (less precision) | float |
| {word} | Single word without quotes | String |
| {bigdecimal} | Large decimal numbers | BigDecimal |
Older projects use regex. You will see them in existing frameworks:
// Regex equivalent of {string}
@When("^the user enters username \\"([^\\"]*)\\"$")
public void enterUsername(String username) { }
// Regex equivalent of {int}
@Then("^the cart should contain (\\d+) items$")
public void cartContains(int count) { }Use Cucumber Expressions for new projects — they are simpler and more readable. Only use regex when you need complex pattern matching that Cucumber Expressions cannot handle.
Data Tables let you pass structured data to a step. They are perfect for form filling or checking multiple values.
Scenario: Fill checkout form
When the user fills in the shipping details:
| firstName | John |
| lastName | Doe |
| email | john@doe.com |
| address | 123 Main St |
| city | Mumbai |
| zipCode | 400001 |import io.cucumber.datatable.DataTable;
import java.util.Map;
import java.util.List;
// Key-value pairs (2 columns)
@When("the user fills in the shipping details:")
public void fillShippingDetails(DataTable dataTable) {
Map<String, String> data = dataTable.asMap(
String.class, String.class);
driver.findElement(By.id("first-name"))
.sendKeys(data.get("firstName"));
driver.findElement(By.id("last-name"))
.sendKeys(data.get("lastName"));
driver.findElement(By.id("email"))
.sendKeys(data.get("email"));
}
// Multiple rows with headers (list of maps)
// Feature:
// When the user adds these products:
// | product | quantity |
// | Laptop | 1 |
// | T-Shirt | 3 |
@When("the user adds these products:")
public void addProducts(DataTable dataTable) {
List<Map<String, String>> items = dataTable.asMaps(
String.class, String.class);
for (Map<String, String> item : items) {
String product = item.get("product");
String qty = item.get("quantity");
// add each product to cart
}
}DocStrings let you pass a block of text to a step. Enclosed in triple quotes:
Scenario: Verify welcome message
Then the page should display:
"""
Welcome to AutoPractice Banking.
Your account is active.
"""@Then("the page should display:")
public void pageDisplays(String expectedText) {
String actual = driver.findElement(
By.id("welcome-block")).getText();
Assert.assertEquals(actual.trim(), expectedText.trim());
}A step definition can be reused across multiple feature files automatically. If both login.feature and dashboard.feature use the step "the user is on the Banking Portal login page", you only need ONE @Given method. Cucumber finds it from the glue package.
If two different step definition methods match the same step text, Cucumber throws an "Ambiguous step definitions" error. Each step text must match exactly one method. If you need different behavior for the same step in different contexts, rethink your step text to make it more specific.
Key Point: Cucumber Expressions ({string}, {int}) capture parameters. Data Tables for structured data. DocStrings for multi-line text.