Great work!

XP to next level

BugEater

DRY Preconditions

Learning Objectives

By the end of this lesson you will be able to:

  • Apply the "Don't Repeat Yourself" principle correctly to Gherkin preconditions
  • Decide whether a given precondition belongs in Background or in an individual scenario
  • Recognize the over-extraction trap and why it hides context from readers

DRY Is About More Than "It's Repeated"

You already know the signal for extracting a Background: a precondition shows up across three or more scenarios. But "it's repeated" isn't quite the whole rule. The real question DRY asks is: is this fact universally true for every scenario in this file, or does it just happen to appear in several of them?

Those are different things. Consider a feature file for a checkout flow:

Feature: Checkout

  Scenario: Standard checkout with a valid card
    Given a cart containing one item priced at $50
    And the customer has a valid credit card on file
    When the customer completes checkout
    Then the order is confirmed

  Scenario: Checkout with an expired discount code
    Given a cart containing one item priced at $50
    And a discount code "SAVE10" that expired yesterday
    When the customer applies the discount code
    Then the discount is rejected

  Scenario: Checkout with insufficient stock
    Given a cart containing one item priced at $50
    And only 0 units of that item remain in stock
    When the customer completes checkout
    Then the order is rejected with an out-of-stock error

"A cart containing one item priced at $50" is universal — every scenario needs it, and it means the same thing every time. That's a real Background candidate. The credit card, the discount code, and the stock level are each relevant to exactly one scenario — they describe what makes that case special, not a fact shared by the whole file.

What Belongs Where

Belongs in Background — universally true, identical across every scenario in the file, and not the thing under test:

Background:
  Given a cart containing one item priced at $50

Stays in the scenario's own Given — only relevant to that one case, or the very fact that makes the scenario distinct:

Scenario: Checkout with an expired discount code
  Given a discount code "SAVE10" that expired yesterday
  When the customer applies the discount code
  Then the discount is rejected

If a precondition is the differentiator between scenarios, it must never move to Background — doing so would erase the one thing that makes each scenario worth having.

The Over-Extraction Trap

It's tempting, once you've learned Background, to shove everything into it "to be safe." Resist this. A bloated Background that includes details only some scenarios actually need creates a new problem: a reader looking at just one scenario has to scroll up and mentally filter through Background steps that don't even apply to what they're reading.

# Over-extracted — most scenarios below don't need the discount code
Background:
  Given a cart containing one item priced at $50
  And a discount code "SAVE10" that is currently active
  And the customer has a valid credit card on file

Now every scenario silently "has" an active discount code and a credit card on file, whether or not that's relevant — and a reader of the out-of-stock scenario has no way to tell, just by reading that scenario, which of those Background facts actually matter to it.

Why This Matters for Business Readers

A Background that's too thin defeats its purpose — you're back to copy-paste. A Background that's too thick hides the specific setup that makes a scenario worth writing in the first place, which is exactly the information a business analyst needs to confirm the scenario is testing what they think it's testing.

Pro Tip: Ask "would removing this line change which scenarios are still correctly described?" If removing it from Background would break every scenario equally, it belongs there. If it would only matter to one or two, it belongs in that scenario's own Given.

Key Takeaways

  • DRY for Gherkin means "universally true for every scenario," not just "appears more than once"
  • A precondition that differentiates one scenario from another must stay local to that scenario
  • Over-using Background hides the specific setup a reader needs to understand one scenario in isolation
  • Test each candidate line by asking whether removing it would affect every scenario equally

Quiz

What is the real question DRY asks about a candidate precondition, beyond "does it repeat"?

A discount-code feature has one scenario about an expired code and one about an active code. Where should "a discount code 'SAVE10' that expired yesterday" live?

Why is "shove everything into Background just to be safe" a trap?

What test can you apply to check whether a line truly belongs in Background?