Bad scenarios
In short: A bad scenario can pass and still do harm: a long journey with many "When" steps, a scenario that relies on the previous one, a check of a database field instead of what the customer sees, buttons and colours, "And" with details that do not matter. Each has a fix: split it, give it its own start, check what is visible, keep what matters.
Problem
Two hundred scenarios nobody reads
The team has 200 scenarios. They take 40 minutes to run. One failed last night: "The full customer journey", 26 steps. It failed at step 19.
The developer spends half an hour reading it. It turns out the bug is in the promo code, and the scenario is about the cart. Meanwhile three more scenarios fail, because they rely on the same cart from "The full journey".
All the scenarios used to pass. But they did not help.
The idea
Five familiar smells
Some kinds of scenarios turn up in every project. They are called "smells": something is wrong, even if it passes.
| Smell | What it looks like | Why it hurts | Fix |
|---|---|---|---|
| a long journey | many "When" and "Then" steps one after another | when it fails, nobody knows which behaviour is broken | every behaviour is its own scenario |
| coupled scenarios | a scenario with no start that relies on the previous one | run alone or in another order, it fails | every scenario carries its own "Given" |
| checking internals | "Then in the orders table…", "Then the service is called…" | it breaks when the code changes even though the rule has not | check what the customer sees |
| screen details | buttons, colours, fields, seconds | it breaks with every new design | declarative steps |
| "And" everywhere | eight lines of "And" with names, addresses, phones | the important part is lost among the unimportant | keep only what the result depends on |
You have already seen some of them in the lesson on declarative scenarios. Here you will fix the two most common ones.
Try it
Which smell?
Exercise
The journey
1. The cart. The editor holds a scenario that fills the cart step by step.
Split the journey into two scenarios with one "When" each: the tenth item is accepted, the eleventh is refused. Each must start from its own cart and catch all four bugs.
Solution
Feature: At most 10 of a product
Scenario: The tenth item is accepted
Given the cart has 9 of the product
When I add 1 more
Then the cart has 10 of the product
Scenario: The eleventh item is refused
Given the cart has 10 of the product
When I add 1 more
Then adding is refused
And the cart has 10 of the product
The two scenarios start right at the interesting point: 9 items and 10 items. You do not have to fill a cart from zero to check the boundary. After the refusal you also check what is left in the cart: without that check, the system that empties the cart on a refusal slips through.
The idea
Every scenario from scratch
Scenarios run separately. Each starts with an empty system: no cart, no customer, nothing from the previous one. The tools may run them in a different order, just one, or several at once.
That is why a scenario that relies on the previous one is a trap. In the file it looks fine, because you read top to bottom. But run alone, it has nothing to start from.
Exercise
The coupled scenarios
2. Then an order of 50 €. The second scenario has no start.
Run the scenarios and see why the second one fails on the correct system. Then fix it so it can run on its own.
Solution
Feature: Free delivery
Scenario: A small order
Given a cart of 49.99 €
When I place the order
Then delivery is 4.90 €
Scenario: An order of 50 €
Given a cart of 50.00 €
When I place the order
Then delivery is free
Run alone, the second scenario has no cart. In the file it looked like it continued the first one, but every scenario starts from scratch. With "Given a cart of 50.00 €" it carries its own start and can run in any order.
The idea
Internals and details
The other two smells are fixed the same way: you check what the customer sees.
Feature: Free delivery
Scenario: Delivery under the boundary Given a customer called Anna Smith And the address 5 High Street, London And the phone 07700 900123 And a cart of 49.99 € When I place the order Then the delivery_fee field in the orders table is 490 And the "Pay" button is greenThe important part here is two lines: the amount and the delivery. The name, address and phone do not affect delivery, but you have to read them to understand that. The database field is right today, but tomorrow the fee might be stored in euros, not cents. And the button is design.
The fixed scenario is three lines: a cart of 49.99 €, I place the order, delivery is 4.90 €. The details do not disappear from the system. They are just not part of this behaviour.
More precisely, if you are curious
The word "smell" comes from code smells in Martin Fowler's book on refactoring (1999), where Kent Beck and Fowler describe signs of code that works but is hard to change. For scenarios the names are not standardised: different books call them slightly differently.
The Gherkin Reference in the Cucumber documentation gives one yardstick: a background longer than 4 lines probably holds details that should become higher-level steps. The same goes for a long "Given" with many "And" steps.
"Checking internals" does not mean the database is never tested. Component and integration tests check exactly that, and they have their place in the module on test levels. But a Gherkin scenario is an acceptance test: it talks about the behaviour the business accepts.
Test
Check yourself
Related lessons
Section titled "Related lessons"- Builds on: Why programs fail · Given, When, Then · Scenario Outline and Examples · What, not how
- Continues in: Living documentation
- Tasks on this topic: Scenarios in Gherkin