Two problems appear in every feature file that grows beyond a handful of scenarios: repeated setup steps that appear identically at the top of every scenario, and the same scenario that needs to run with different data. Gherkin has first-class solutions for both — Background and Scenario Outline.
Background: shared preconditions without repetition
Imagine a feature file for a product search page. Every scenario needs a logged-in user on the products page. Without Background:
Scenario: Search by name
Given the user is logged in as "standard_user"
And the user is on the products page
When the user searches for "Laptop"
Then the results should contain "Laptop"
Scenario: Search with no results
Given the user is logged in as "standard_user"
And the user is on the products page
When the user searches for "XYZNONEXISTENT"
Then the results should be empty
Scenario: Search is case-insensitive
Given the user is logged in as "standard_user"
And the user is on the products page
When the user searches for "LAPTOP"
Then the results should contain "Laptop"The first two Given steps are identical in every scenario. With Background:
Feature: Product Search
Background:
Given the user is logged in as "standard_user"
And the user is on the products page
Scenario: Search by name
When the user searches for "Laptop"
Then the results should contain "Laptop"
Scenario: Search with no results
When the user searches for "XYZNONEXISTENT"
Then the results should be empty
Scenario: Search is case-insensitive
When the user searches for "LAPTOP"
Then the results should contain "Laptop"Background runs before every scenario in the file — exactly like @BeforeMethod in TestNG or @BeforeEach in JUnit 5. Three scenarios → Background runs three times. The steps in Background map to the same step definitions as anywhere else.
Rules for using Background effectively:
- Use it only for steps shared by all scenarios in the feature. If Background applies to 4 out of 5 scenarios, move the odd one out to a different feature file, or use a
@Beforehook filtered by tag. - Keep Background short — 2–4 steps maximum. A 10-step Background is a sign the feature has too much shared complexity.
- Background steps appear before the first
Scenario:keyword. - Background cannot have its own scenario name.
Scenario Outline: the same scenario with different data
Some behaviours must be verified across multiple data combinations. Login validation is the classic example: valid credentials succeed, wrong password fails, empty fields fail. Without Scenario Outline:
Scenario: Login with valid credentials succeeds
Given the login page is open
When the user enters "standard_user" and "secret_sauce"
Then the result should be "success"
Scenario: Login with wrong password fails
Given the login page is open
When the user enters "standard_user" and "wrong_pass"
Then the result should be "error"
Scenario: Login with empty email fails
Given the login page is open
When the user enters "" and "secret_sauce"
Then the result should be "error"Three scenarios, nearly identical structure. With Scenario Outline:
Feature: Login Validation
Scenario Outline: Login with various credentials
Given the login page is open
When the user enters "<username>" and "<password>"
Then the result should be "<expected>"
Examples:
| username | password | expected |
| standard_user | secret_sauce | success |
| standard_user | wrong_pass | error |
| | secret_sauce | error |
| standard_user | | error |
| locked_out_user | secret_sauce | error |Cucumber produces five independent test executions — one per data row in the Examples table. Each execution has its own test name (derived from the row values), its own pass/fail status, and its own entry in the report. Row 3 can fail while the others pass; you get granular failure reporting.
The <placeholder> syntax in the scenario text is replaced by the matching column value for each row. Column headers become the placeholder names — <username> maps to the username column.
Multiple Examples blocks
You can have more than one Examples block under a Scenario Outline, with different names:
Scenario Outline: Login with various credentials
Given the login page is open
When the user enters "<username>" and "<password>"
Then the result should be "<expected>"
Examples: Valid credentials
| username | password | expected |
| standard_user | secret_sauce | success |
Examples: Invalid credentials
| username | password | expected |
| standard_user | wrong | error |
| | any_pass | error |The named blocks make reports easier to read — they group results by category rather than showing all rows in one flat list.
Scenario Outline vs Background: which to use
These solve different problems:
- Background — shared setup steps that run before every scenario. Not data-driven.
- Scenario Outline — the same scenario behaviour repeated with different input data. Produces multiple executions.
They can be combined: a Background handles login, a Scenario Outline handles the data-driven scenarios.
How Scenario Outline executions flow
Step 1 of 6
Parse Scenario Outline
Cucumber reads the Scenario Outline as a template. The <placeholder> tokens mark where data row values will be substituted.
Combining Background and Scenario Outline
Feature: Login Validation
Background:
Given the login page is open
Scenario Outline: Login attempt with various credentials
When the user enters "<username>" and "<password>"
Then the result should be "<expected>"
Examples:
| username | password | expected |
| standard_user | secret_sauce | success |
| standard_user | wrong_pass | error |Background (Given the login page is open) runs before each of the two Scenario Outline executions. Total step executions: Background × 2 + Outline steps × 2.
⚠️ Common mistakes
- Background steps that not all scenarios need. If one scenario needs a logged-in admin but another tests the guest homepage, Background is the wrong tool. Use a
@Beforehook filtered by tag (@Before("@authenticated")). - Overloading the Examples table. An Examples table with 30 rows is hard to maintain. Split into multiple named Examples blocks by category, or use external data (covered in a later course).
- Scenario Outline for non-data-driven scenarios. If every row in your Examples table is testing a fundamentally different behaviour (not just different data values), they should be separate named scenarios, not outline rows.
- Forgetting
<angle brackets>in the scenario text. If the placeholder in the scenario body doesn't exactly match the column header (case-sensitive), Cucumber will not substitute the value — the literal<username>text appears in the step instead.
🎯 Practice task
Refactor the login feature file from Chapter 1 using Background and Scenario Outline. 35 minutes.
- Open
login.featurefrom the previous lesson. It has at least two scenarios that share the sameGiven the login page is openstep. Extract it into aBackground. - If you have multiple login scenarios with different credentials and different expected outcomes, merge them into a
Scenario Outlinewith an Examples table (at least 3 rows: valid credentials, wrong password, empty username). - Run all scenarios. Confirm each row produces a separate test execution in the report.
- Add a second Examples block called
"Edge cases"with 2 rows for unusual inputs (very long username, SQL injection string). The assertions should still work — if the app returns an error for both, the expected column should beerror. - Stretch: create a
product-search.featurewith aBackgroundthat logs in, and aScenario Outlinethat searches for 4 different product names, each asserting whether the result set is non-empty or empty. Confirm Cucumber produces 4 separate test executions.
Next lesson: passing structured data into steps using data tables.