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 "[email protected]"
  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.