Automating Cucumber Data Table to Java Object Mapping in Your Cucumber Tests

As a Java developer, using Cucumber for Behavior-Driven Development (BDD) can be a great way to ensure that your code meets business requirements by writing tests in plain language. One of the most powerful features of Cucumber is the ability to use Data Tables in feature files. However, manually mapping these tables to Java objects can be repetitive and error-prone.

To streamline this process, the library cucumber-datatable-to-bean-mapping aims to automatically map Cucumber Data Tables to Java objects. In this article, I will walk you through the library's functionality and how you can easily integrate it into your Cucumber projects to save time and reduce boilerplate code.

How To Use cucumber-datatable-to-bean-mapping

Let’s dive into how you can use this library in your project.

Step 1: Add the Library to Your Project

First, you need to add the cucumber-datatable-to-bean-mapping library to your Maven or Gradle project. 

For Maven, add the following dependency to your pom.xml:

XML
 
<dependency>
    <groupId>io.github.deblockt</groupId>
    <artifactId>cucumber-datatable-to-bean-mapping</artifactId>
    <version>1.1.2</version>
</dependency>


For Gradle, add the following to your build.gradle:

Groovy
 
implementation 'io.github.deblockt:cucumber-datatable-to-bean-mapping:1.1.2'


Step 2: Define Your Java Bean

Create a Java bean class that represents the data structure you want to map from the Cucumber Data Table. Use Java annotations to specify the mapping between the table headers and the bean fields.

For example, suppose you have a feature file with a Data Table like this:

Gherkin
 
Given the following users exist
  | first name | last name | email                  |
  | John       | Doe       | john.doe@example.com   |
  | Jane       | Smith     | jane.smith@example.com |


You can create a Java bean for the User:

Java
 
import com.deblock.cucumber.datatable.annotations.DataTableWithHeader;
import com.deblock.cucumber.datatable.annotations.Column;

@DataTableWithHeader
public class User {
    @Column
    private String firstName;
    @Column
    private String lastName;
    @Column
    private String email;

    // Getter / Setter
}

// Or use a record
@DataTableWithHeader
public record User(@Column String firstName, @Column String lastName, @Column String email) {}


Step 3: Annotate Your Step Definitions

Now you can use this class on your step definition. 

For example:

Java
 
import io.cucumber.java.en.Given;
import java.util.List;

public class UserStepDefinitions {

    @Given("the following users exist")
    public void theFollowingUsersExist(List<User> users) {
        for (User user : users) {
            System.out.println("Creating user: " + user.getFirstName() + " " + user.getLastName());
            // Logic to handle user creation
        }
    }
}


Step 4: Run Your Cucumber Tests

That's all: you can now run your Cucumber tests and the library will automatically map the data table to a list of User objects. The Users parameter in your step definition will be populated with the data from your feature file, and you can easily iterate over the users and perform any necessary logic.

Configuration

Column Extra Configuration

The previous example uses the default library configuration. However, you can provide more details in the @Column annotation, such as setting field descriptions, defining whether fields are mandatory, or specifying default values for columns.

Java
 
@DataTableWithHeader
public class User {
    @Column(mandatory = false, description = "The custom first name")
    private String firstName;

    @Column(defaultValue = "Doe")
    private String lastName;

    @Column(value = "overridden email name")
    private String email;

    // Getters and Setters
}


Library Configuration

By default, column names are generated from field names using a human-readable format (camelCase is converted to spaced words). You can override this behavior by adding specific properties to the cucumber.properties file.

Properties files
 
cucumber.datatable.mapper.name-builder-class=com.deblock.cucumber.datatable.mapper.name.UseFieldNameColumnNameBuilder


With this configuration, the column names will directly use the field names without converting them to a human-readable format.

Additionally, while it's generally recommended to annotate all Data Table columns with the @Column annotation, you can configure the library to use all class fields as Data Table columns automatically.

Properties files
 
cucumber.datatable.mapper.field-resolver-class=com.deblock.cucumber.datatable.mapper.datatable.fieldresolvers.ImplicitFieldResolver


Using this configuration, you can define your Java beans more succinctly:

Java
 
@DataTableWithHeader
public class User {
    private String firstName;
    private String lastName;
    private String email;

    @Ignore
    private String externalInformation;

    // Getters and Setters
}


By configuring the library this way, all fields will be automatically included as Data Table columns unless explicitly ignored using the @Ignore annotation.

Why Use cucumber-datatable-to-bean-mapping?

Conclusion

The cucumber-datatable-to-bean-mapping library simplifies the process of converting Cucumber Data Tables into Java objects, saving time and reducing the likelihood of errors in your BDD tests. By adding this library to your project, you can streamline your step definitions and focus more on writing meaningful tests rather than boilerplate code.

To get started with the library, read the library documentation for more information, including additional configuration options and advanced usage scenarios. 

Happy coding!

 

 

 

 

Top