1. Introduction
Cucumber is a popular tool in behavior-driven development (BDD) for writing test scenarios in plain language. Utilizing parameters in Cucumber allows for dynamic and reusable tests.
In this article, we’ll discuss essential techniques for using Cucumber parameters in Java testing.
2. Understanding Cucumber Parameters
Cucumber parameters are placeholders in feature files that allow scenarios to be executed with different inputs.
Here’s a basic example illustrating string parameters:
Feature: User Login
Scenario: User logs into the system
Given the user enters username "john_doe" and password "password123"
When the user clicks on the login button
Then the dashboard should be displayed
Step definitions capture these parameters using annotations:
public class LoginSteps {
private static final Logger logger = LoggerFactory.getLogger(LoginSteps.class);
@Given("the user enters username {string} and password {string}")
public void enterUsernameAndPassword(String username, String password) {
logger.info("Username: {}, Password: {}", username, password);
}
@When("the user clicks on the login button")
public void clickLoginButton() {
logger.info("Login button clicked");
}
@Then("the dashboard should be displayed")
public void verifyDashboardDisplayed() {
logger.info("Dashboard displayed");
}
}
Here, we define step definitions that correspond to each step in the feature file. The @Given, @When, and @Then annotations capture the parameters specified in the scenario and pass them to the corresponding methods.
3. Using DataTable for List Parameters
DataTable allows testing with multiple sets of data.
Let’s look at an example of how to use DataTable:
Scenario: Verify user login with multiple accounts
Given the user tries to log in with the following accounts:
| username | password |
| john_doe | password1 |
| jane_smith | password2 |
When each user attempts to log in
Then each user should access the system successfully
We handle DataTable with a list of custom objects:
public class DataTableLoginSteps {
private static final Logger logger = LoggerFactory.getLogger(DataTableLoginSteps.class);
@Given("the user tries to log in with the following accounts:")
public void loginUser(List<UserCredentials> credentialsList) {
for (UserCredentials credentials : credentialsList) {
logger.info("Username: {}, Password: {}", credentials.getUsername(), credentials.getPassword());
}
}
public static class UserCredentials {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
}
In this example, we use the DataTable class to map the data table from the feature file to a list of UserCredentials objects. This allows us to iterate over the list and process each set of credentials individually.
4. Using Regular Expressions
Regular expressions (regex) allow flexible parameter matching. Let’s consider the following example for email validation:
Scenario: Verify email validation
Given the user enters email address "john.doe@example.com"
When the user submits the registration form
Then the email should be successfully validated
We capture the email address parameter with step definitions:
public class RegexLoginSteps {
private static final Logger logger = LoggerFactory.getLogger(RegexLoginSteps.class);
@Given("the user enters email address \"([^\"]*)\"")
public void enterEmailAddress(String emailAddress) {
logger.info("Email: {}", emailAddress);
}
}
Here, we use a regular expression to capture the email address parameter. The regex \”([^\”]*)\” matches any string enclosed in double quotes, allowing us to handle dynamic email addresses.
5. Using Custom Transformer
Custom transformers convert input strings to specific Java types. Let’s look at an example:
Scenario: Verify date transformation
Given the user enters birthdate "1990-05-15"
When the user submits the registration form
Then the birthdate should be stored correctly
Next, let’s define the step definitions to handle data transformation:
public class LocalDateTransformer {
private static final Logger logger = LoggerFactory.getLogger(LocalDateTransformer.class);
@ParameterType("yyyy-MM-dd")
public LocalDate localdate(String dateString) {
return LocalDate.parse(dateString);
}
@Given("the user enters birthdate {localdate}")
public void enterBirthdate(LocalDate birthdate) {
logger.info("Birthdate: {}", birthdate);
}
}
In this method, we define a custom transformer using the @ParameterType annotation. This transformer converts the input string in “yyyy-MM-dd” format into a LocalDate object, allowing us to work with date objects directly in our step definitions.
6. Conclusion
Passing lists as parameters in Cucumber enhances our ability to test various data sets efficiently. Whether we use DataTable, regular expressions, or custom transformers, the goal remains consistent: to streamline the testing process and ensure comprehensive coverage.
As usual, we can find the full source code and examples over on GitHub.