Cucumber-JVM Java library providing annotation-based step definitions for Behavior-Driven Development (BDD) testing
—
Comprehensive hook system for test setup, teardown, and step-level interception across different scopes. Hooks provide precise control over test execution lifecycle with support for conditional execution based on tags and explicit ordering.
Execute method before each scenario with optional tag filtering and execution order control.
/**
* Execute method before each scenario
* @param value Tag expression for conditional execution (default: "")
* @param order Execution order, lower numbers run first (default: 10000)
*/
@Before(value = "", order = 10000)
public void beforeScenario() { }
/**
* Before hook with Scenario parameter for access to scenario metadata
*/
@Before
public void beforeScenario(Scenario scenario) {
String scenarioName = scenario.getName();
Collection<String> tags = scenario.getSourceTagNames();
}Usage Examples:
import io.cucumber.java.Before;
import io.cucumber.java.Scenario;
public class HookDefinitions {
// Run before every scenario
@Before
public void setUp() {
// Global setup logic
}
// Run only before scenarios tagged with @database
@Before("@database")
public void setUpDatabase() {
// Database-specific setup
}
// Run only before scenarios tagged with @web but not @mobile
@Before("@web and not @mobile")
public void setUpWebDriver() {
// Web driver setup
}
// Run first (order 1) before other setup hooks
@Before(order = 1)
public void setUpFirst() {
// High priority setup
}
// Access scenario information
@Before
public void beforeWithScenario(Scenario scenario) {
System.out.println("Starting scenario: " + scenario.getName());
if (scenario.getSourceTagNames().contains("@slow")) {
// Special handling for slow tests
}
}
}Execute method after each scenario with access to scenario results and execution order control.
/**
* Execute method after each scenario
* @param value Tag expression for conditional execution (default: "")
* @param order Execution order, higher numbers run first (default: 10000)
*/
@After(value = "", order = 10000)
public void afterScenario() { }
/**
* After hook with Scenario parameter for access to results and reporting
*/
@After
public void afterScenario(Scenario scenario) {
Status status = scenario.getStatus();
boolean failed = scenario.isFailed();
}Usage Examples:
import io.cucumber.java.After;
import io.cucumber.java.Scenario;
import io.cucumber.java.Status;
public class HookDefinitions {
// Run after every scenario
@After
public void tearDown() {
// Global cleanup logic
}
// Run only after scenarios tagged with @database
@After("@database")
public void tearDownDatabase() {
// Database cleanup
}
// Run last (order 0) after other teardown hooks
@After(order = 0)
public void tearDownLast() {
// Final cleanup
}
// Handle failed scenarios
@After
public void afterScenario(Scenario scenario) {
if (scenario.isFailed()) {
// Take screenshot, log error details, etc.
scenario.log("Scenario failed: " + scenario.getName());
// Attach screenshot for failed web tests
if (scenario.getSourceTagNames().contains("@web")) {
byte[] screenshot = takeScreenshot();
scenario.attach(screenshot, "image/png", "Failed Screenshot");
}
}
}
// Report scenario status
@After
public void reportStatus(Scenario scenario) {
Status status = scenario.getStatus();
switch (status) {
case PASSED:
scenario.log("✓ Test passed successfully");
break;
case FAILED:
scenario.log("✗ Test failed");
break;
case SKIPPED:
scenario.log("○ Test was skipped");
break;
default:
scenario.log("? Test status: " + status);
}
}
}Execute method before each step with optional tag filtering and execution order control.
/**
* Execute method before each step
* @param value Tag expression for conditional execution (default: "")
* @param order Execution order, lower numbers run first (default: 10000)
*/
@BeforeStep(value = "", order = 10000)
public void beforeStep() { }
/**
* BeforeStep hook with Scenario parameter
*/
@BeforeStep
public void beforeStep(Scenario scenario) {
// Access scenario context before each step
}Usage Examples:
import io.cucumber.java.BeforeStep;
import io.cucumber.java.Scenario;
public class HookDefinitions {
// Log each step execution
@BeforeStep
public void logStep(Scenario scenario) {
scenario.log("About to execute step in: " + scenario.getName());
}
// Prepare for web steps only
@BeforeStep("@web")
public void beforeWebStep() {
// Web-specific step preparation
webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}
// High priority step preparation
@BeforeStep(order = 1000)
public void prepareStep() {
// Critical step preparation
}
}Execute method after each step with access to step results and execution order control.
/**
* Execute method after each step
* @param value Tag expression for conditional execution (default: "")
* @param order Execution order, higher numbers run first (default: 10000)
*/
@AfterStep(value = "", order = 10000)
public void afterStep() { }
/**
* AfterStep hook with Scenario parameter
*/
@AfterStep
public void afterStep(Scenario scenario) {
// Access scenario context after each step
}Usage Examples:
import io.cucumber.java.AfterStep;
import io.cucumber.java.Scenario;
public class HookDefinitions {
// Take screenshot after each step in web tests
@AfterStep("@web")
public void screenshotAfterStep(Scenario scenario) {
if (scenario.getSourceTagNames().contains("@screenshot")) {
byte[] screenshot = takeScreenshot();
scenario.attach(screenshot, "image/png", "Step Screenshot");
}
}
// Log step completion
@AfterStep
public void logStepCompletion(Scenario scenario) {
scenario.log("Completed step in: " + scenario.getName());
}
// Cleanup after critical steps
@AfterStep("@cleanup")
public void cleanupAfterStep() {
// Cleanup logic
}
}Execute static method before all scenarios are executed. These hooks run once per test execution.
Note: This annotation is currently experimental and may change in future versions.
/**
* Execute static method before all scenarios
* @param order Execution order, lower numbers run first (default: 10000)
* Note: BeforeAll methods must be static and take no parameters
* API Status: EXPERIMENTAL
*/
@BeforeAll(order = 10000)
public static void beforeAll() { }Usage Examples:
import io.cucumber.java.BeforeAll;
public class HookDefinitions {
// Global test suite setup
@BeforeAll
public static void globalSetup() {
// Initialize test environment
System.setProperty("test.environment", "integration");
// Start external services
startDatabaseService();
startWebServer();
}
// High priority global setup
@BeforeAll(order = 1)
public static void criticalSetup() {
// Critical infrastructure setup
loadConfiguration();
initializeLogging();
}
// Database preparation
@BeforeAll(order = 100)
public static void prepareDatabase() {
// Setup test database
runDatabaseMigrations();
seedTestData();
}
}Execute static method after all scenarios have been executed. These hooks run once per test execution.
Note: This annotation is currently experimental and may change in future versions.
/**
* Execute static method after all scenarios
* @param order Execution order, higher numbers run first (default: 10000)
* Note: AfterAll methods must be static and take no parameters
* API Status: EXPERIMENTAL
*/
@AfterAll(order = 10000)
public static void afterAll() { }Usage Examples:
import io.cucumber.java.AfterAll;
public class HookDefinitions {
// Global test suite cleanup
@AfterAll
public static void globalCleanup() {
// Shutdown external services
stopWebServer();
stopDatabaseService();
// Generate reports
generateTestReport();
}
// High priority cleanup (runs first)
@AfterAll(order = 1000)
public static void criticalCleanup() {
// Critical cleanup that must happen first
flushLogs();
closeConnections();
}
// Final cleanup (runs last)
@AfterAll(order = 1)
public static void finalCleanup() {
// Final teardown
cleanupTempFiles();
resetSystemProperties();
}
}All hooks support tag expressions for conditional execution:
// Simple tag
@Before("@database")
// Multiple tags (AND)
@Before("@web and @integration")
// Tag exclusion (NOT)
@Before("not @skip")
// Complex expressions
@Before("(@web or @mobile) and not @slow")
@After("@database and not (@readonly or @mock)")
// Tag expressions with parentheses
@BeforeStep("(@critical or @important) and not @skip")Hook execution order is controlled by the order parameter:
@Before(order = 1) // Runs first
@Before(order = 100) // Runs second
@Before // Runs third (default order 10000)
@Before(order = 20000) // Runs last
@After(order = 20000) // Runs first (highest number)
@After // Runs second (default order 10000)
@After(order = 100) // Runs third
@After(order = 1) // Runs last (lowest number)Install with Tessl CLI
npx tessl i tessl/maven-io-cucumber--cucumber-java