Background, Scenario Outline, and Examples

9 min read

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 @Before hook 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 @Before hook 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.

  1. Open login.feature from the previous lesson. It has at least two scenarios that share the same Given the login page is open step. Extract it into a Background.
  2. If you have multiple login scenarios with different credentials and different expected outcomes, merge them into a Scenario Outline with an Examples table (at least 3 rows: valid credentials, wrong password, empty username).
  3. Run all scenarios. Confirm each row produces a separate test execution in the report.
  4. 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 be error.
  5. Stretch: create a product-search.feature with a Background that logs in, and a Scenario Outline that 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.

// tip to track lessons you complete and pick up where you left off across devices.