Cucumber-JVM 4 Anonymous Parameter Types

Introduction

XStream was removed from Cucumber-JVM in version 3 for various reasons. Though it reduced a lot of complexities, it removed functionality which automatically transformed a String to a object and DataTable into a collection of objects. This now requires code for each transformation to define a DataTableType or ParamterType in the TypeRegistry for these cases. This has been made easier in Cucumber-JVM 4.2.0 for Parameters and for DataTables in 4.0.0 by using Jackson ObjectMapper. Refer to official announcements for version 4.0.0 and version 4.2.0.

This article explains in brief the handling of parameters in Cucumber-JVM versiona 3x to 4x. Refer these for a detailed explanation of migration from version 2 to version 3 of Parameter and Datatable.

Source Code & Versions

This article uses the Cucumber-JVM version 4.4.0. The source code for parameter conversion for versions 3.x to 4.1.1 is located here. The source code for parameter conversion for version 4.2.0 and above is located here. The below scenario containing conversion of parameter to a object (Customer) and conversion to enum (Beverage) is the main concern.

Scenario: Parameter scenario class and enum
    Given Customer John orders COFFEE
    Given Customer Jane orders LEMONADE

From Cucumber 3.x to Cucumber 4.1.1

This conversion needs to be handled by defining a ParameterType in the TypeRegistry class. Cucumber Expression is used in the step definition method. The relevant parts of code for the step definition class and typeregistry class are mentioned below. The feature file is located here.

//Configuration class method
public void configureTypeRegistry(TypeRegistry registry) {

    registry.defineParameterType(new ParameterType<>("customer", ".*?", Customer.class, Customer::new));
    registry.defineParameterType(new ParameterType<>("beverage", ".*?", Beverage.class, (String s) -> Beverage.valueOf(s)));
}

//Step Definition method
@Given("Customer {customer} orders {beverage}")
public void customerOrders(Customer customer, Beverage beverage) {
    
    System.out.println("Customer name is " + customer.getName() + " orders " + beverage);
}

Cucumber 4.2.0 And Above – Anonymous Parameter Types

The automatic conversion is back without explicit code for each parameter type. This is accomplished by using an object mapping tool like Jackson ObjectMapper. This also supports Enum and other types like BigInteger, BigDecimal, Byte, Short, Integer, Long, Float, Double, Date. Below changes need to be made from the previous version for this to work.

  1. Remove the explicit parameter type ie. defineParameterType method for the specific type from configureTypeRegistry method.
  2. Remove the parameter type variable within the curly brackets from the step definition pattern in case of Cucumber Expression. If this is not done then cucumber will search for the parameter type to be explicitly set as in the previous version.
  3. Create a transformer class that implements ParameterByTypeTransformer interface which does the actual type creation. This same class can also implement other interfaces like TableEntryByTypeTransformer, TableCellByTypeTransformer which make life easier when dealing with DataTable conversion introduced in version 4.0.0.
  4. Pass an object of the class created above to the setDefaultParameterTransformer method of the TypeRegistry object.

The relevant parts of code for the step definition class and typeregistry class are mentioned below. The feature file is located here.

//Configuration class method and inner class
public void configureTypeRegistry(TypeRegistry registry) {

    JacksonTableTransformer jacksonTableTransformer = new JacksonTableTransformer();
    registry.setDefaultParameterTransformer(jacksonTableTransformer);
}	

private static final class JacksonTableTransformer implements ParameterByTypeTransformer{
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    public Object transform(String s, Type type) {
        return objectMapper.convertValue(s, objectMapper.constructType(type));
    }
}

//Step Definition method
@Given("Customer {} orders {}")
public void customerOrders(Customer customer, Beverage beverage) {
    System.out.println("Customer name is " + customer.getName() + " orders " + beverage);
}

The feature file and step definition also contain examples for Date, BigInteger and BigDecimal automatic conversions.

5 thoughts on “Cucumber-JVM 4 Anonymous Parameter Types”

    1. This is related to the cucumber plugin that you are using in your IDE. which IDE r u using? My guess is that the plugin has not been updated to take cucumber expression into account for finding step definitions.

      1. I am using eclipse, Oxygen.3a
        All other steps work fine, the issue is only when I use ananymous parameter {} it gives glue code not found. On execution it is stepping into the code but when manualy trying to step in cmd+ctrl it does not work

  1. Everything works fine with this implementation on execution but compalins glue code not found for string types

Leave a Reply

Your email address will not be published. Required fields are marked *