Provides lambda-based step definitions for Cucumber BDD testing framework with Java 8+ functional interfaces
npx @tessl/cli install tessl/maven-io-cucumber--cucumber-java8@7.22.0Cucumber Java8 provides lambda-based step definitions for the Cucumber BDD (Behavior-Driven Development) testing framework. It enables developers to write test step definitions using lambda expressions and functional interfaces instead of traditional annotation-based approaches, making test code more concise and readable while leveraging Java 8+ functional programming features.
pom.xml:<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java8</artifactId>
<version>7.22.1</version>
<scope>test</scope>
</dependency>import io.cucumber.java8.En;For localized step definitions:
import io.cucumber.java8.Fr; // French
import io.cucumber.java8.De; // German
// Other language interfaces availableFor hooks and test context:
import io.cucumber.java8.Scenario;
import io.cucumber.java8.Status;package com.example.stepdefs;
import io.cucumber.java8.En;
import io.cucumber.datatable.DataTable;
import io.cucumber.docstring.DocString;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CalculatorSteps implements En {
private Calculator calculator;
public CalculatorSteps() {
// Step definitions
Given("a calculator I just turned on", () -> {
calculator = new Calculator();
});
When("I add {int} and {int}", (Integer arg1, Integer arg2) -> {
calculator.push(arg1);
calculator.push(arg2);
calculator.push("+");
});
Then("the result is {double}", (Double expected) -> {
assertEquals(expected, calculator.value());
});
// Hooks
Before((Scenario scenario) -> {
System.out.println("Starting scenario: " + scenario.getName());
});
After((Scenario scenario) -> {
if (scenario.isFailed()) {
scenario.attach("Screenshot".getBytes(), "text/plain", "Debug info");
}
});
// Parameter type
ParameterType("amount", "(\\d+\\.\\d+)\\s([a-zA-Z]+)", (String[] values) ->
new Amount(new BigDecimal(values[0]), Currency.getInstance(values[1])));
// Data table type
DataTableType((Map<String, String> entry) -> new User(
entry.get("name"),
entry.get("email"),
Integer.parseInt(entry.get("age"))
));
}
}Cucumber Java8 is built around functional interfaces and lambda expressions, providing:
Core functionality for defining BDD test steps using lambda expressions. Supports multiple languages and parameter arities (0-9 parameters) with full type safety.
public interface En extends LambdaGlue {
// Given, When, Then, And, But methods with 0-9 parameter support
default void Given(String expression, StepDefinitionBody.A0 body) { ... }
default void Given(String expression, StepDefinitionBody.A1<T1> body) { ... }
// ... up to A9 for 9 parameters
default void When(String expression, StepDefinitionBody.A0 body) { ... }
default void Then(String expression, StepDefinitionBody.A0 body) { ... }
default void And(String expression, StepDefinitionBody.A0 body) { ... }
default void But(String expression, StepDefinitionBody.A0 body) { ... }
}Before and After hooks for scenario and step-level lifecycle management, with support for execution order and tag-based filtering.
// Hook methods in LambdaGlue interface
default void Before(HookBody body) { ... }
default void Before(String tagExpression, HookBody body) { ... }
default void Before(int order, HookBody body) { ... }
default void Before(String tagExpression, int order, HookBody body) { ... }
default void After(HookBody body) { ... }
default void BeforeStep(HookBody body) { ... }
default void AfterStep(HookBody body) { ... }
// Functional interfaces for hook bodies
@FunctionalInterface
interface HookBody {
void accept(Scenario scenario) throws Throwable;
}
@FunctionalInterface
interface HookNoArgsBody {
void accept() throws Throwable;
}Comprehensive transformation system for converting between string representations and Java objects, including parameter types, data table types, doc string types, and default transformers.
// Parameter types with 1-9 parameter support
default <T> void ParameterType(String name, String regexp, ParameterDefinitionBody.A1<T> body) { ... }
// Data table transformers
default <T> void DataTableType(DataTableDefinitionBody<T> body) { ... }
default <T> void DataTableType(DataTableEntryDefinitionBody<T> body) { ... }
default <T> void DataTableType(DataTableRowDefinitionBody<T> body) { ... }
default <T> void DataTableType(DataTableCellDefinitionBody<T> body) { ... }
// Doc string transformers
default <T> void DocStringType(String contentType, DocStringDefinitionBody<T> body) { ... }
// Default transformers
default void DefaultParameterTransformer(DefaultParameterTransformerBody body) { ... }
default void DefaultDataTableCellTransformer(DefaultDataTableCellTransformerBody body) { ... }
default void DefaultDataTableEntryTransformer(DefaultDataTableEntryTransformerBody body) { ... }Test execution context access through the Scenario class, providing test metadata, status information, and reporting capabilities.
public final class Scenario {
public Collection<String> getSourceTagNames() { ... }
public Status getStatus() { ... }
public boolean isFailed() { ... }
public void attach(byte[] data, String mediaType, String name) { ... }
public void attach(String data, String mediaType, String name) { ... }
public void log(String text) { ... }
public String getName() { ... }
public String getId() { ... }
public URI getUri() { ... }
public Integer getLine() { ... }
}
public enum Status {
PASSED, SKIPPED, PENDING, UNDEFINED, AMBIGUOUS, FAILED, UNUSED
}
public final class PendingException extends RuntimeException {
public PendingException() { ... }
public PendingException(String message) { ... }
}// Core functional interfaces for step definitions
interface StepDefinitionBody {
@FunctionalInterface
interface A0 {
void accept() throws Throwable;
}
@FunctionalInterface
interface A1<T1> {
void accept(T1 arg1) throws Throwable;
}
@FunctionalInterface
interface A2<T1, T2> {
void accept(T1 arg1, T2 arg2) throws Throwable;
}
// ... A3 through A9 with similar patterns for up to 9 parameters
}
// Parameter definition functional interfaces
interface ParameterDefinitionBody {
@FunctionalInterface
interface A1<R> {
R accept(String arg1) throws Throwable;
}
// ... A2 through A9 similar to StepDefinitionBody
}
// Data transformation functional interfaces
@FunctionalInterface
interface DataTableDefinitionBody<T> {
T accept(DataTable table) throws Throwable;
}
@FunctionalInterface
interface DataTableEntryDefinitionBody<T> {
T accept(Map<String, String> entry) throws Throwable;
}
@FunctionalInterface
interface DataTableRowDefinitionBody<T> {
T accept(List<String> row) throws Throwable;
}
@FunctionalInterface
interface DataTableCellDefinitionBody<T> {
T accept(String cell) throws Throwable;
}
@FunctionalInterface
interface DocStringDefinitionBody<T> {
T accept(String docString) throws Throwable;
}
@FunctionalInterface
interface DefaultParameterTransformerBody {
Object accept(String fromValue, Type toValueType) throws Throwable;
}
@FunctionalInterface
interface DefaultDataTableCellTransformerBody {
Object accept(String fromValue, Type toValueType) throws Throwable;
}
@FunctionalInterface
interface DefaultDataTableEntryTransformerBody {
Object accept(Map<String, String> fromValue, Type toValueType) throws Throwable;
}