Behavior-Driven Development & Specification by Example

Software Testing Strategy

Chapter 8 · Behavior-Driven Development & Specification by Example

Documentation & Runbooks named a real problem: documentation decays silently, looking exactly as authoritative the day it goes stale as the day it was written. BDD is a direct, concrete answer for a specific category of documentation — the description of what the system does — by making the description itself executable. This chapter verifies exactly what that buys you, side by side against the plain prose it replaces.

Given-When-Then, on a Real Policy

def scenario_gold_member_gets_ten_percent_off(): # GIVEN a cart total of $100 cart_total = 100 # AND a GOLD member checking out membership_tier = "GOLD" # WHEN the discount is applied result = apply_discount(cart_total, membership_tier) # THEN the total is reduced by 10% assert result == 90.0
Verified directly — the scenario reads as a spec and runs as a test
scenario_gold_member_gets_ten_percent_off() passes against the real apply_discount() function. Anyone reading the Given/When/Then comments alone — no Python experience required — learns the exact business rule; anyone running the file confirms the rule is actually true of the current code, in the same three lines.

The Real Test: What Happens When the Policy Changes

def apply_discount_v2(cart_total, membership_tier): if membership_tier == "GOLD": return cart_total * 0.85 # CHANGED: 15% off, was 10% ... STATIC_DOC = """GOLD members receive a 10% discount at checkout."""
Verified directly — the static prose stayed wrong; nothing forces it to change
After the policy changes from 10% to 15%, STATIC_DOC — a plain markdown string, not connected to any code — still reads "GOLD members receive a 10% discount." Nothing about running the program, the tests, or a build checks it. It will read as correct to anyone who trusts it until a human happens to notice the mismatch by hand — exactly Documentation & Runbooks Chapter 7's own silent-decay finding.
Verified directly — the BDD scenario failed loudly the moment it was re-run
The identical scenario_gold_member_gets_ten_percent_off, re-run against the new apply_discount_v2 with its own expected value left unchanged: fails immediately — "expected 90.0, got 85.0." The scenario doesn't quietly become wrong; it announces the mismatch the next time anyone runs it, typically in CI, long before a human would have caught the prose drift by inspection.
Verified directly — updating the scenario deliberately becomes the new source of truth
Once the 15% policy is confirmed as the real, intended behavior, updating the scenario's own expected value to 85.0 is a deliberate, reviewed code change — not a silent edit nobody notices. The scenario now passes again, and reading it tells anyone the current, correct policy, with no way for it to quietly drift out of sync a second time without failing first.
Static prose documentationBDD scenario
When the code changes underneath itStays exactly as written — silently wrongFails immediately the next run — loudly wrong
How the mismatch gets foundA human happens to notice, eventually, or neverAutomatically, on the next CI run
Updating itEasy to forget — no signal that it's neededForced — the scenario won't pass until it's updated

Where This Connects

This chapter's findingWhat it connects to
Static documentation staying silently wrong after a real policy changeDocumentation & Runbooks Chapter 7's own silent-decay problem, reproduced concretely rather than described abstractly
A scenario failing loudly instead of drifting quietlyChapter 3's own brittleness material — the difference here is the scenario is supposed to fail when real behavior changes, which is the entire point rather than a bug

Hands-On Exercises

Exercise 1

Write a second Given-When-Then scenario for this chapter's own apply_discount function covering PLATINUM members (20% off). Verify it passes against the original function, then verify it also fails when re-run against a modified version where PLATINUM's own discount changes to 25%.

📄 View solution
Exercise 2

Write a static prose description (a plain string, like this chapter's own STATIC_DOC) for a third membership tier, SILVER, that gives a 5% discount. Add SILVER support to apply_discount, then change the SILVER discount to 8% and verify the static doc, once again, stays silently wrong with no automatic check catching it.

📄 View solution
Exercise 3

Write a Given-When-Then scenario for a member with no recognized tier (e.g. membership_tier = "BASIC"), asserting no discount is applied. Verify it passes against both apply_discount and apply_discount_v2 unchanged — and explain why this particular scenario is unaffected by the GOLD-tier policy change that broke the other one.

📄 View solution

Chapter 8 Quick Reference

  • Given-When-Then: a scenario that reads as a spec for a human and runs as a test for CI, in the same lines
  • Verified: after a real policy change, static prose documentation stayed silently wrong — no automatic check ever catches it
  • Verified: the identical BDD scenario, re-run against the changed code, failed immediately and loudly
  • The real value: not that BDD prevents behavior from changing — it's that a change gets discovered on the next run, not whenever a human happens to notice
  • Directly answers: Documentation & Runbooks' own silent-decay problem, for the specific category of documentation BDD scenarios can express
  • Next chapter: Testing Legacy & Untested Code — what to do when none of this exists yet