Cucumber Hooks are the equivalent of TestNG @BeforeMethod and @AfterMethod. Tags are the equivalent of TestNG groups. Together, they control how tests are set up, torn down, and organized.
The Hooks class manages browser lifecycle. @Before launches the browser before each scenario. @After takes a screenshot on failure and closes the browser after each scenario.
package com.autopractice.hooks;
import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java.Scenario;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class Hooks {
private static ThreadLocal<WebDriver> driverThread =
new ThreadLocal<>();
@Before
public void setUp(Scenario scenario) {
System.out.println("Starting: " + scenario.getName());
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driverThread.set(driver);
}
@After
public void tearDown(Scenario scenario) {
WebDriver driver = driverThread.get();
if (scenario.isFailed() && driver != null) {
byte[] screenshot = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.BYTES);
scenario.attach(screenshot, "image/png",
"Failure-" + scenario.getName());
}
if (driver != null) {
driver.quit();
driverThread.remove();
}
}
public static WebDriver getDriver() {
return driverThread.get();
}
}Two important things: (1) scenario.attach() embeds the screenshot directly in the Cucumber HTML report — no separate file management needed. (2) ThreadLocal ensures each thread gets its own browser during parallel execution.
You can make hooks run only for specific tagged scenarios:
// Only runs before @banking scenarios
@Before("@banking")
public void setUpBanking() {
getDriver().get("https://www.testerrank.com/banking");
}
// Only runs before @shopping scenarios
@Before("@shopping")
public void setUpShopping() {
getDriver().get("https://www.testerrank.com/shopping");
}
// Control hook execution order (lower runs first)
@Before(order = 0)
public void globalSetUp() {
// Runs first — browser setup
}
@Before(order = 1)
public void specificSetUp() {
// Runs second — navigation
}Tags are labels prefixed with @ that you attach to Features and Scenarios. They work like TestNG groups:
@banking @regression
Feature: Banking Dashboard
@smoke @critical
Scenario: Dashboard loads after login
Given the user has logged in
Then the dashboard should show the balance
@regression
Scenario: Transaction history displays
Given the user has logged in
Then recent transactions should be visible
@wip
Scenario: Download statement
# Work in progress — not ready for CI
Given the user has logged in
Then the user can download a PDF statement# Run only @smoke tests
mvn test -Dcucumber.filter.tags="@smoke"
# Run @smoke OR @regression
mvn test -Dcucumber.filter.tags="@smoke or @regression"
# Run @smoke AND @banking
mvn test -Dcucumber.filter.tags="@smoke and @banking"
# Run everything EXCEPT @wip
mvn test -Dcucumber.filter.tags="not @wip"
# Complex: (smoke or regression) but not wip
mvn test -Dcucumber.filter.tags="(@smoke or @regression) and not @wip"Standard tags in most teams: @smoke (quick sanity, run on every build), @regression (full suite, run nightly), @critical (must-pass for release), @wip (work in progress, exclude from CI), @banking/@shopping (module tags). Tag everything from day one.
Q: What are Cucumber hooks? How are they different from Background?
A: Both run before each scenario, but they serve different purposes. Background is Gherkin — it contains steps written in plain English, visible in the feature file and in reports. @Before is Java — it contains technical code (browser setup, driver init) that is not visible in the feature file. Use Background for test behavior that stakeholders should see (like "Given the user is on the login page"). Use @Before for technical plumbing (like initializing ChromeDriver). @After is used for teardown — I capture screenshots on failure using scenario.attach() and close the browser.
Key Point: @Before/@After manage browser lifecycle. Tags organize and filter tests. scenario.attach() embeds screenshots in reports.