skip to content

When is a Scenario Outline with an Examples table better than separate scenarios?

level: middleimportance: must knowfreq 62%

answer

  1. One rule, several values
  2. Each row becomes its own scenario
  3. Headers bind to placeholders by name
  4. Different meaning means different scenario
  5. Illustrate boundaries, do not enumerate

basics

~20 s

A Scenario Outline states one behaviour once with placeholders, and its Examples table supplies a row per case, each running as its own scenario. Use it when rows differ only in data, not in meaning.

solid answer

~50 s

A **Scenario Outline** carries placeholders in its steps; the **Examples** table's header names bind to those placeholders **by name**, and each row is expanded into a full scenario with its own name, its own result and its own run of any shared context. It is the right shape when the rows are one rule illustrated with several values — the columns then show a reviewer exactly which dimensions the rule varies over, which is how a domain expert spots a missing case. Prefer separate scenarios when the cases mean different things: when the outcome differs in kind rather than in value, when some rows need extra context, or when one case is important enough to deserve a name and prose of its own. The failure mode is the table that becomes an exhaustive matrix — that is enumeration, not illustration, and it belongs in a cheaper parameterised check below the scenario suite.

code

pseudocode · 10 lines
pseudocode
Scenario Outline: A rate push is rejected outside the channel's lead time
  Given the channel "<channel>" accepts bookings <min lead> days ahead
  When a rate is pushed for a stay starting <requested lead> days ahead
  Then the push is <outcome>

  Examples: lead-time boundaries
    | channel   | min lead | requested lead | outcome  |
    | wholesale | 3        | 2              | rejected |
    | wholesale | 3        | 3              | accepted |
    | direct    | 0        | 0              | accepted |

go deeper

for a junior

Know the two parts and how they connect: placeholders in the steps, an Examples table whose headers carry the same names, and one scenario executed per row. Be able to read an outline aloud with a row substituted in.

for a middle

Explain the mechanics beneath the syntax: expansion happens before execution, binding is by header name rather than column position, cell values arrive as text, and each row independently re-runs any shared context in the file.

for a senior

Show judgment about size and meaning. Be ready to say when a table has stopped illustrating a rule and started enumerating a matrix, what that costs a long regression pack in run time and report readability, and where those cases should move instead.

for a principal

Own the boundary between specification and data-driven checking. Decide what belongs in business-readable examples versus a cheaper parameterised layer, and be able to justify why deleting rows from a table does not reduce the coverage that matters.

### The construct A **Scenario Outline** is a scenario written once, with placeholders where the varying values go, followed by an **Examples** table whose header names match those placeholders and whose rows supply the values. Before anything runs, the outline is expanded: every row becomes a full scenario in its own right, with the placeholders substituted. Five rows means five scenarios, each with its own name in the report, its own pass or fail, and its own run of any shared context steps in the file. ``` Scenario Outline: Rate push is rejected outside the channel's allowed lead time Given the channel "<channel>" accepts bookings <min lead> days ahead When a rate is pushed for a stay starting <requested lead> days ahead Then the push is <outcome> Examples: lead-time boundaries | channel | min lead | requested lead | outcome | | wholesale | 3 | 2 | rejected | | wholesale | 3 | 3 | accepted | | direct | 0 | 0 | accepted | ``` The binding is **by name**, not by position: the header `min lead` fills the `<min lead>` placeholder wherever it appears. A header that matches no placeholder is simply unused, and a placeholder with no matching header is not substituted — the step text keeps the literal angle-bracketed token and either fails to match a definition or, worse, matches one and tests something nobody intended. Column names and placeholder names must be kept identical, and a mismatch is a genuinely nasty silent defect. ### When the outline is the right call The test is whether the rows are **the same behaviour with different data** or **different behaviours**. One rule, several illustrative values, one shared sentence of intent: that is an outline, and writing those as separate scenarios would be copy-paste that hides the shared rule in the noise. The outline also gives a reviewer something valuable — the varying dimensions of the rule are laid out as columns, so a domain expert can look at the table and say "you're missing the case where the lead time is negative". ### When separate scenarios win * **The Then differs in kind, not in value.** If one case ends in a rejection message and another ends in a queued retry, an `<outcome>` column flattens two different behaviours into one sentence that describes neither well. Write two scenarios. * **The rows need different context.** If half the table only makes sense after an extra Given, the outline is being asked to carry two rules. * **A single row matters enough to deserve a name.** The headline example of a rule — the one the team argues about — reads better as a named scenario with its own prose than as row four of a table. * **The table has become a data dump.** This is the important judgement. A table of forty-seven rows enumerating a parameter cross-product is data-driven testing wearing a business-readable costume: nobody outside the team reads it, it is slower than the equivalent check one level down (each row pays the full scenario cost, including any shared context steps), and it drowns the two or three rows that actually illustrate the rule. Keep the outline to the handful of rows a person would use to *explain* the rule — the boundaries and one representative value from each equivalence class — and push exhaustive enumeration to a cheaper layer. Concretely: in a **340-case regression pack** for a hotel booking channel manager, an outline that expanded a channel-by-lead-time-by-rate-plan matrix into ninety rows was the single largest contributor to run time, and when the channel connector developed **an intermittent timeout**, ninety red rows made the report unreadable. Cut to six rows chosen at the boundaries, the same rule was still specified, the report still failed when the rule broke, and the matrix moved to a lower-level parameterised check where it ran in a fraction of the time. ### Practical details worth knowing * Many dialects allow **more than one Examples block** under a single outline, each with its own name and its own tags — useful for separating happy-path rows from edge-case rows, or for tagging one block as slow. * Placeholders are usually substituted **inside step arguments too**, including inside a table or a text block attached to a step, which is how a row can vary part of a payload rather than a whole step. * Row values arrive as text. Any interpretation — a number, a date, an empty cell meaning "absent" versus "empty string" — is a decision made when the step is implemented, and an empty cell is a classic source of ambiguity. Prefer an explicit token over a blank cell when the distinction matters. * Failure reporting is per row. A candidate who claims you cannot tell which case failed is describing a badly named outline, not a limitation of the construct: give the outline a name that reads well once the values are substituted.

  • What happens when an Examples column header does not match any placeholder in the steps?
    The column is simply unused, and the reverse case is worse: a placeholder with no matching header is never substituted, so the step runs with the literal angle-bracketed token. It may fail to match a definition, or match one and quietly assert something nobody intended. Names must be identical, and this silent mismatch is worth a review check.
  • How many rows should an Examples table carry?
    Enough to illustrate the rule and no more — typically a handful chosen at the boundaries and one representative value per equivalence class. A table someone could read aloud to explain the rule is the right size. Forty-plus rows enumerating a cross-product means the pack is paying full scenario cost for data that a lower-level parameterised check would run far more cheaply.
  • Can one Scenario Outline have more than one Examples block?
    In most dialects, yes — each block can carry its own name and its own tags. It is a good way to separate happy-path rows from edge-case rows while keeping the single statement of the rule, or to mark one block as slow so it can be selected differently.

saying these in an interview costs you the question

  • Thinks the outline runs once for the whole table
  • Uses an outline to hold an exhaustive parameter matrix
  • Names Examples columns differently from the step placeholders
  • Claims a report cannot show which row failed
  • Copy-pastes near-identical scenarios rather than parameterising one rule

context