Skip to main content

Cucumber Data Tables

The CUCUMBER_DATA_TABLE mode — Gherkin data tables are passed as Cucumber DataTable objects, giving you the full Cucumber DataTable API for conversions and POJO mapping.

Why this mode exists — migrating from Cucumber

Unlike the other data-table modes, this one is not about how you would write a spec from scratch: it is here so an existing Cucumber suite can move across. Step methods that already consume io.cucumber.datatable.DataTable keep working as-is, so you can adopt SpecBinder without rewriting your data-table handling first.

Migrating from Cucumber covers the rest of what changes on the way over.

Source: examples/migrating-from-cucumber/example-1 on GitHub.

What this demonstrates​

  • @Gherkin2JUnitOptions(dataTableParameterType = CUCUMBER_DATA_TABLE) switches the mode
  • Step methods receive DataTable instead of List<XxxParam>
  • The generator emits a createDataTable(String tableLines) helper that parses pipe-delimited text blocks
  • You must provide a getTableConverter() method on the class you annotate or a class it extends — the generated helper calls it, so it has to be visible from the generated class
  • The concrete test class implements the steps, turning each DataTable into typed rows with asList(...)
  • Access to the full Cucumber API: asList(), asMap(), asMaps(), POJO mapping
  • Requires the cucumber-java dependency
  • The spec stays a .feature file, co-located with its marker class — a migrating suite keeps its existing files

When to pick this mode​

AspectLIST_OF_OBJECT_PARAMS (default)CUCUMBER_DATA_TABLE
Parameter typeList<GeneratedParam>DataTable
Type safetyCompile-time (typed fields)Runtime (string-based)
POJO mappingAutomatic (generated classes)Manual (DataTableTypeRegistry)
DependenciesNonecucumber-java
Best forNew projects, compile-time safetyMigrating from Cucumber, complex conversions

Class hierarchy​

BaseFeature.java                    (@Gherkin2JUnitOptions(dataTableParameterType = CUCUMBER_DATA_TABLE))
└→ ShoppingCartFeature.java (marker — getTableConverter(), row type registration)
└→ ShoppingCartScenarios.java (generated, abstract — DataTable step methods, createDataTable() helper)
└→ ShoppingCartTest.java (your concrete class, implements the steps)

The option sits on a base class, so every marker that extends it gets DataTable parameters. The marker carries the table converter and the row types; the steps live in the concrete test, as in any other example.

Generated code​

The generated class declares each table step with a DataTable parameter and builds the table at the call site:

public abstract void myCartContainsTheFollowingProducts(DataTable dataTable);

myCartContainsTheFollowingProducts(createDataTable("""
| name | qty | unit price |
| Wireless Headphones | 1 | 59.99 |
| Coffee Beans 1kg | 3 | 12.50 |
"""));

createDataTable(...) is generated too, unless a class above already provides one. It splits the text into rows and cells and hands them to getTableConverter().

POJO mapping with DataTableTypeRegistry​

The marker registers how a row becomes a Product:

registry.defineDataTableType(new DataTableType(
Product.class,
(Map<String, String> row) -> new Product(
row.get("name"),
Integer.parseInt(row.get("qty")),
Double.parseDouble(row.get("unit price"))
)
));

The step method in ShoppingCartTest then gets typed rows in one call — the same code an existing Cucumber step definition would contain:

@Override
public void myCartContainsTheFollowingProducts(DataTable dataTable) {
products = dataTable.asList(Product.class);
}

@Override
public void theCartShouldContain$p1Products(Integer expectedCount) {
assertEquals(expectedCount, products.size());
}

Files​

FilePurpose
src/test/java/.../ShoppingCart.featureFeature with data tables, co-located with its marker
src/test/java/.../BaseFeature.javaBase class with @Gherkin2JUnitOptions(dataTableParameterType = CUCUMBER_DATA_TABLE)
src/test/java/.../ShoppingCartFeature.javaMarker class — bare @Gherkin2JUnit, getTableConverter() and row type registration
src/test/java/.../ShoppingCartTest.javaConcrete test implementing the steps with DataTable.asList(...)
pom.xmlAdds the cucumber-java dependency

Run it​

cd examples/migrating-from-cucumber/example-1
mvn test