Skip to content

Background Steps

Background steps provide a way to share common setup across all scenarios in a feature. They run before each scenario, ensuring consistent starting conditions.

Basic Syntax

Use the Background keyword before your scenarios:

gherkin
Feature: Shopping Cart

  Background:
    Given I am a logged-in customer
    And I have an empty cart

  Scenario: Add item to cart
    When I add "Widget" to the cart
    Then I should see 1 item in my cart

  Scenario: Add multiple items
    When I add "Widget" to the cart
    And I add "Gadget" to the cart
    Then I should see 2 items in my cart

Both scenarios start with a logged-in customer and an empty cart.

How Background Works

Execution Order

For each scenario in a feature:

  1. Fresh context is created
  2. All Background steps execute
  3. Scenario steps execute
  4. Context is discarded
Feature with Background + 2 Scenarios:

Scenario 1:
  [New Context] → Background Steps → Scenario 1 Steps → [Discard]

Scenario 2:
  [New Context] → Background Steps → Scenario 2 Steps → [Discard]

Fresh Context

Each scenario gets a completely fresh context. Changes made during one scenario don't affect others:

gherkin
Feature: Counter

  Background:
    Given the counter is 0

  Scenario: First increment
    When I increment the counter
    Then the counter should be 1  # Starts from 0

  Scenario: Second increment
    When I increment the counter
    Then the counter should be 1  # Also starts from 0, not 1!

Multiple Background Steps

You can have multiple steps in a Background:

gherkin
Feature: Admin Dashboard

  Background:
    Given the database is seeded
    And a user "admin@test.com" exists
    And the user has role "administrator"
    And I am logged in as "admin@test.com"

  Scenario: View users
    When I visit the users page
    Then I should see a list of users

  Scenario: Create user
    When I create a new user
    Then the user count should increase by 1

Step Definitions for Background

Background steps use the same step definitions as regular steps:

php
use TestFlowLabs\PestTestAttributes\Given;

class SetupSteps
{
    #[Given('the database is seeded')]
    public function seedDatabase(): void
    {
        $this->artisan('db:seed');
    }

    #[Given('I am logged in as {email}')]
    public function loggedInAs(string $email): void
    {
        $user = User::where('email', $email)->first();
        $this->actingAs($user);
    }

    #[Given('I have an empty cart')]
    public function emptyCart(): Cart
    {
        return new Cart();
    }
}

Context Injection from Background

Return values from Background steps are available in scenario steps:

gherkin
Feature: User Orders

  Background:
    Given a user "John" exists
    And the user has an active subscription

  Scenario: Place order
    When the user places an order       # Can inject User
    Then the order should be confirmed
php
#[Given('a user {name} exists')]
public function userExists(string $name): User
{
    return User::factory()->create(['name' => $name]);
}

#[Given('the user has an active subscription')]
public function activeSubscription(User $user): Subscription
{
    // $user is injected from previous background step
    return Subscription::factory()
        ->for($user)
        ->active()
        ->create();
}

#[When('the user places an order')]
public function placeOrder(User $user, Subscription $subscription): Order
{
    // Both are available from background
    return Order::factory()
        ->for($user)
        ->create();
}

Multi-Language Background

Background has keywords in all 70+ Gherkin languages:

gherkin
Background:
  Given I am logged in
gherkin
# language: tr
Geçmiş:
  Diyelim ki sisteme giriş yaptım
gherkin
# language: de
Grundlage:
  Angenommen ich bin eingeloggt
gherkin
# language: fr
Contexte:
  Soit je suis connecté
gherkin
# language: es
Antecedentes:
  Dado que estoy conectado

Best Practices

Keep Background Short

Background should contain only essential shared setup:

Good:

gherkin
Background:
  Given I am a logged-in customer

Avoid:

gherkin
Background:
  Given I am on the home page
  And I click "Login"
  And I enter username "john@test.com"
  And I enter password "secret"
  And I click "Submit"
  And I wait for dashboard to load
  And I dismiss the welcome popup

Use for Common Prerequisites

Background is ideal for:

  • Authentication state
  • Database seeding
  • Common entity creation
  • Application state setup

Don't Overuse

If only some scenarios need certain setup, don't put it in Background:

gherkin
# Instead of this:
Background:
  Given a user exists
  And the user is an admin  # Only needed for some scenarios!

# Do this:
Scenario: Admin can delete users
  Given a user exists
  And the user is an admin
  When I delete a user
  ...

Scenario: User can view profile
  Given a user exists  # No admin needed here
  When I view my profile
  ...

Background vs Shared Steps

Sometimes a shared step is cleaner than background:

gherkin
# Using Background
Background:
  Given I am logged in as an admin

Scenario: Admin task 1
  When I do something admin-y
  ...

# Alternative: Explicit in each scenario
Scenario: Admin task 1
  Given I am logged in as an admin
  When I do something admin-y
  ...

Choose based on:

  • Background: When ALL scenarios need it
  • Explicit steps: When clarity is more important

Complete Example

gherkin
Feature: E-commerce Checkout
  As a customer
  I want to complete a purchase
  So that I can receive my products

  Background:
    Given I am a registered customer
    And I have items in my cart:
      | product       | quantity |
      | Wireless Mouse | 1       |
      | USB Cable     | 2        |
    And my shipping address is set

  @smoke
  Scenario: Successful checkout with credit card
    When I proceed to checkout
    And I select "Credit Card" as payment method
    And I enter valid card details
    And I confirm the order
    Then I should see an order confirmation
    And I should receive a confirmation email

  Scenario: Checkout with insufficient stock
    Given "USB Cable" has only 1 item in stock
    When I proceed to checkout
    Then I should see a stock warning
    And I should be able to adjust my cart

  Scenario: Apply discount code
    When I proceed to checkout
    And I apply discount code "SAVE10"
    Then my total should be reduced by 10%
php
class CheckoutSteps
{
    private Cart $cart;
    private ?Order $order = null;

    #[Given('I am a registered customer')]
    public function registeredCustomer(): User
    {
        return User::factory()->create();
    }

    #[Given('I have items in my cart:')]
    public function itemsInCart(User $user, TableNode $table): Cart
    {
        $this->cart = new Cart($user);

        foreach ($table->getRows() as $row) {
            $product = Product::where('name', $row['product'])->first();
            $this->cart->add($product, (int) $row['quantity']);
        }

        return $this->cart;
    }

    #[Given('my shipping address is set')]
    public function shippingAddressSet(User $user): void
    {
        Address::factory()->for($user)->create();
    }

    #[When('I proceed to checkout')]
    public function proceedToCheckout(): void
    {
        $this->order = $this->cart->startCheckout();
    }

    #[Then('I should see an order confirmation')]
    public function shouldSeeConfirmation(): void
    {
        expect($this->order->status)->toBe('confirmed');
    }
}

Released under the MIT License.