Cucumber BDD — 30 Interview Questions (Answers & Examples)¶
BDD specs in Gherkin, mapped to Java step definitions via glue, driven by a JUnit/TestNG runner — the interview-ready reference.
Q1. What is Cucumber and what is BDD?¶
Cucumber is an open-source tool that runs executable specifications written in plain-language Gherkin, and BDD (Behaviour Driven Development) is a practice of writing business-readable specs in natural language to bridge business, dev, and QA.
In plain words: you describe behaviour in a language everyone can read, and Cucumber turns those descriptions into automated tests.
Feature: Login
Scenario: Valid user logs in
Given the user is on the login page
When they log in with valid credentials
Then they see the dashboard
Q2. How does Cucumber support BDD?¶
Cucumber supports BDD by parsing Gherkin .feature files (the shared specification) and executing each step through matching automation code, so a living document doubles as a test suite.
In plain words: the same file the business reads is the file that runs and verifies the software.
# One Gherkin step below maps to one automated step-definition method
Given the account balance is 100
Q3. What are the main components of Cucumber?¶
The core components are feature files (Gherkin scenarios), step definitions (Java glue code), hooks, a runner class, and reporting plugins.
In plain words: specs, the code behind the specs, setup/teardown, the entry point, and the output.
// Feature file -> src/test/resources/features/login.feature
// Step defs -> src/test/java/stepdefs/LoginSteps.java
// Hooks -> src/test/java/stepdefs/Hooks.java
// Runner -> src/test/java/runners/TestRunner.java
Q4. What is a feature file in Cucumber?¶
A feature file is a plain-text .feature file written in Gherkin that groups related scenarios describing one feature of the application.
In plain words: it is the human-readable test spec that lives alongside your code.
Feature: Shopping cart
As a shopper I want to add items so that I can buy them
Scenario: Add a single item
Given an empty cart
When I add a "book"
Then the cart has 1 item
Q5. What is the syntax of a feature file?¶
A feature file starts with the Feature: keyword and an optional description, followed by one or more Scenario:/Scenario Outline: blocks whose steps begin with Gherkin keywords.
In plain words: Feature at the top, then scenarios made of Given/When/Then steps.
Feature: <title>
<optional free-text description>
Background:
Given <shared precondition>
Scenario: <scenario title>
Given <precondition>
When <action>
Then <expected outcome>
And <extra step>
But <negative step>
Q6. What are Gherkin keywords?¶
Gherkin keywords are the reserved words that structure a feature file: Feature, Scenario, Scenario Outline, Given, When, Then, And, But, Background, and Examples.
In plain words: the fixed vocabulary Cucumber understands.
Feature: Keyword tour
Background:
Given a logged-in user
Scenario Outline: Search
When I search for "<term>"
Then I see results
And the count is "<n>"
But no error banner
Examples:
| term | n |
| shoes | 5 |
Q7. What is the purpose of the Given, When, Then keywords?¶
Given sets up preconditions, When performs the action under test, and Then asserts the expected outcome.
In plain words: arrange (Given), act (When), assert (Then).
Scenario: Withdraw cash
Given my balance is 200 # precondition
When I withdraw 50 # action
Then my balance should be 150 # expected outcome
Q8. How do you write scenarios in Cucumber?¶
A scenario is written under the Scenario: keyword as a concrete example of behaviour, expressed as a sequence of Given/When/Then steps.
In plain words: one scenario = one specific case of how the feature behaves.
Scenario: Reject invalid password
Given the user is on the login page
When they submit username "raj" and password "wrong"
Then an "Invalid credentials" error is shown
Q9. What is a Scenario Outline?¶
A Scenario Outline is a data-driven template that runs the same steps multiple times, substituting <placeholder> values from an Examples table.
In plain words: one scenario, many rows of data.
Scenario Outline: Login attempts
Given the login page
When I log in as "<user>" / "<pass>"
Then I see "<result>"
Examples:
| user | pass | result |
| raj | pass123 | dashboard |
| raj | bad | error |
Q10. How do you use Examples in Cucumber?¶
The Examples keyword defines a table of values whose column headers match the <placeholders> in a Scenario Outline, producing one test run per data row.
In plain words: each row of the Examples table becomes its own executed scenario.
Scenario Outline: Tax calc
When I buy an item costing <price>
Then tax charged is <tax>
Examples:
| price | tax |
| 100 | 18 |
| 200 | 36 |
Q11. How are step definitions written in Cucumber?¶
Step definitions are Java methods annotated with @Given/@When/@Then whose pattern (regex or Cucumber Expression) matches the text of a Gherkin step.
In plain words: each plain-English step is backed by one Java method.
@Given("the account balance is {int}")
public void balanceIs(int amount) {
account.setBalance(amount);
}
@When("I withdraw {int}")
public void withdraw(int amount) {
account.withdraw(amount);
}
Q12. What is the role of glue code in Cucumber?¶
Glue is the package(s) containing step definitions and hooks; Cucumber scans this glue path to link Gherkin steps to executable code.
In plain words: "glue" tells Cucumber where your step-definition classes live.
@CucumberOptions(
features = "src/test/resources/features",
glue = {"stepdefs", "hooks"} // packages to scan
)
Q13. How do you map steps in the feature file to code?¶
Cucumber maps a step to code by matching the step text against the pattern in a step-definition annotation, using regular expressions or Cucumber Expressions with typed parameters.
In plain words: the words in the feature step must match the pattern on a Java method.
@When("I add a {string} to the cart") // Cucumber Expression
public void addItem(String item) { cart.add(item); }
Q14. How do you handle parameterization in Cucumber steps?¶
Parameters are captured with Cucumber Expression tokens ({int}, {string}, {word}, {float}) or regex capture groups, and passed as typed arguments into the step method.
In plain words: values in the step text flow into the method as method arguments.
@Then("the total is {float} for {int} items")
public void total(float total, int count) {
assertEquals(total, cart.total(count), 0.01);
}
Q15. What are hooks in Cucumber?¶
Hooks are @Before/@After (and @BeforeStep/@AfterStep) annotated methods that run automatically around scenarios for setup and teardown, and they can be tagged to run selectively.
In plain words: reusable setup/cleanup that runs without appearing in the feature file.
@Before
public void setUp() { driver = new ChromeDriver(); }
@After
public void tearDown() { driver.quit(); }
Q16. How do @Before and @After hooks work?¶
@Before runs before every scenario and @After runs after every scenario; both execute once per scenario (not once per step), and ordering can be controlled with order and narrowed with tags.
In plain words: bookends around each scenario for setup and cleanup.
@Before(order = 1)
public void startBrowser() { /* runs first */ }
@After(order = 1) // higher order runs earlier on teardown
public void screenshotOnFail(Scenario s) {
if (s.isFailed()) s.attach(bytes, "image/png", "failure");
}
@Before("@api") // tagged hook: only for @api scenarios
public void apiSetup() { }
Q17. How do you handle tags in Cucumber?¶
Tags are @label annotations placed above features, scenarios, or examples to group and filter tests; they enable selective execution and tagged hooks.
In plain words: sticky labels you attach to scenarios to slice your suite.
@smoke @regression
Scenario: Checkout succeeds
Given a cart with items
When I pay
Then the order is confirmed
Q18. How do you run scenarios with specific tags?¶
Tagged runs are selected with a tag expression via the runner's tags option or -Dcucumber.filter.tags on the command line, using and/or/not operators.
In plain words: tell Cucumber "run these tags, skip those."
Q19. What is the difference between Scenario and Scenario Outline?¶
A Scenario runs its steps once with fixed values, while a Scenario Outline runs the same steps repeatedly using placeholders filled from an Examples table.
In plain words: one is a single case, the other is a data-driven template.
| Scenario | Scenario Outline |
|---|---|
| Runs exactly once | Runs once per Examples row |
| Uses concrete literal values | Uses <placeholders> |
No Examples table |
Requires an Examples table |
| Best for a single unique case | Best for data-driven / multiple inputs |
Q20. How do you share data between steps?¶
State is shared between step-definition classes using dependency injection (e.g., PicoContainer) or a shared context/World object injected into each class — avoiding static fields where possible.
In plain words: pass a shared "context" object into your step classes instead of using globals.
public class TestContext { // shared, DI-managed
public String userId;
public Response lastResponse;
}
public class LoginSteps {
private final TestContext ctx;
public LoginSteps(TestContext ctx) { this.ctx = ctx; } // PicoContainer injects
}
Q21. How do you integrate Cucumber with Selenium?¶
Cucumber integrates with Selenium by driving a WebDriver inside step definitions, typically creating the driver in a @Before hook and quitting it in @After.
In plain words: the step methods contain the Selenium code that clicks and types.
@When("I log in with {string} and {string}")
public void login(String user, String pass) {
driver.findElement(By.id("user")).sendKeys(user);
driver.findElement(By.id("pass")).sendKeys(pass);
driver.findElement(By.id("submit")).click();
}
Q22. How do you generate reports in Cucumber?¶
Reports are produced via the plugin option in the runner, generating HTML, JSON, or JUnit XML; richer dashboards come from third-party plugins like the Maven Cucumber Reporting or Allure.
In plain words: add plugins and Cucumber writes report files after the run.
@CucumberOptions(
plugin = {
"pretty",
"html:target/cucumber-report.html",
"json:target/cucumber.json",
"io.qameta.allure.cucumber7jvm.AllureCucumber7Jvm"
}
)
Q23. What is the purpose of the cucumber.options in the runner class?¶
@CucumberOptions (older builds also read the cucumber.options system property) configures the run — features path, glue packages, tags, plugins, and dry-run — controlling what Cucumber executes and how it reports.
In plain words: the central knob that tells the runner what to run and how.
@CucumberOptions(
features = "src/test/resources/features",
glue = "stepdefs",
tags = "@smoke",
plugin = {"pretty", "html:target/report.html"},
dryRun = false
)
// Note: @CucumberOptions/cucumber.options is the older JUnit4 style; modern
// Cucumber (JUnit 5 / junit-platform) prefers junit-platform.properties.
Q24. What are Data Tables in Cucumber?¶
A Data Table is a tabular block of data attached directly to a single step, received in the step method as a DataTable (or a list of maps/objects) — distinct from a Scenario Outline's Examples.
In plain words: pass a table of data into one step, not run the scenario multiple times.
@Given("the following users exist:")
public void users(DataTable table) {
List<Map<String,String>> rows = table.asMaps();
rows.forEach(r -> db.insert(r.get("name"), r.get("role")));
}
Q25. How do you handle exceptions in Cucumber steps?¶
Exceptions are handled by letting assertion/runtime failures mark the scenario failed, or by catching and asserting where needed; an @After(Scenario) hook can capture diagnostics like screenshots on failure.
In plain words: a thrown exception fails the step; use hooks to log or screenshot on failure.
@After
public void onFail(Scenario scenario) {
if (scenario.isFailed()) {
byte[] png = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
scenario.attach(png, "image/png", scenario.getName());
}
}
Q26. Can Cucumber tests be run in parallel? How?¶
Yes — parallel execution is achieved through the JUnit 5 platform (cucumber.execution.parallel.enabled=true), the TestNG AbstractTestNGCucumberTests runner, or Maven Surefire/Failsafe forking.
In plain words: configure the runner/build to fork scenarios across threads.
# junit-platform.properties (JUnit 5)
cucumber.execution.parallel.enabled=true
cucumber.execution.parallel.config.strategy=fixed
cucumber.execution.parallel.config.fixed.parallelism=4
// TestNG alternative
public class ParallelRunner extends AbstractTestNGCucumberTests {
@Override @DataProvider(parallel = true)
public Object[][] scenarios() { return super.scenarios(); }
}
Q27. What is the difference between Background and Before hooks?¶
A Background is Gherkin Given steps shared by every scenario in a feature and appears in the report, whereas a @Before hook is Java code that runs before each scenario but stays invisible in the feature file.
In plain words: Background is visible shared spec steps; a hook is hidden shared code.
| Background | @Before hook |
|---|---|
| Written in Gherkin (feature file) | Written in Java (step-def class) |
| Shows as steps in the report | Not shown as steps |
| Scoped to one feature file | Applies to all glued scenarios (or by tag) |
| For business-readable preconditions | For technical setup (driver, DB, config) |
Q28. How do you organize feature files in a project?¶
Feature files live under src/test/resources (e.g., features/), grouped into subfolders by module or domain, with step definitions in matching packages under src/test/java.
In plain words: mirror your app's modules with folders of features and parallel step-def packages.
src/test/resources/features/
login/login.feature
cart/checkout.feature
src/test/java/stepdefs/
login/LoginSteps.java
cart/CheckoutSteps.java
Q29. What is the role of the runner class in Cucumber?¶
The runner class is the JUnit/TestNG entry point (@RunWith(Cucumber.class) in JUnit 4, or @Suite on JUnit 5) that discovers feature files, wires the glue, applies options, and launches execution.
In plain words: the class that kicks off the whole Cucumber run.
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/resources/features",
glue = "stepdefs",
plugin = {"pretty", "html:target/report.html"}
)
public class TestRunner { }
Q30. How do you integrate Cucumber with Maven or Gradle?¶
Integration is done by adding Cucumber dependencies (cucumber-java, cucumber-junit/cucumber-junit-platform-engine) plus a JUnit engine, and letting Surefire (Maven) or the test task (Gradle) execute the runner during the build.
In plain words: declare the Cucumber libraries and run mvn test / gradle test.
<!-- Maven -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit-platform-engine</artifactId>
<version>7.18.0</version>
<scope>test</scope>
</dependency>