Combination therapy for requirements using BDD and UML
Ask ten experienced developers how to write a use case and you’ll get ten different answers. Some will give you a two-paragraph narrative. Others will reach for a structured template with pre-conditions, post-conditions, and alternate flows. A few will argue use cases are dead and pull out user stories. The format wars are real, and they have a cost—when vendor and client each carry a different mental model of what “a use case” means, the gap shows up in the delivered software.
That gap is expensive. In fixed-price projects especially, ambiguous requirements aren’t just an inconvenience; they become contractual disputes.
What’s broken about conventional use cases
The problem isn’t use cases as a concept. The problem is that the form is underspecified. Every organisation develops its own flavour, its own level of detail, its own assumptions about what belongs in the main flow versus an alternate flow. Without a shared, precise format, two people reading the same document can build two very different systems.
There’s also a participation problem. Stakeholders often can’t read or critique a use case written in technical prose. They sign off without genuinely validating the requirement. The bug report three months later is the first real review.
BDD as a requirements language
Behaviour-Driven Development, introduced by Dan North, was designed to solve exactly this problem. BDD stories are structured in plain English using a format that’s both human-readable and machine-executable:
Title: Withdraw cash from ATM
As a bank customer
I want to withdraw cash from an ATM
So that I can access my money without visiting a branch
Scenario: Account has sufficient funds
Given the account balance is $100
And the card is valid
And the machine contains enough money
When the customer requests $20
Then the ATM should dispense $20
And the account balance should be $80
And the card should be returned
Scenario: Account has insufficient funds
Given the account balance is $10
When the customer requests $20
Then the ATM should not dispense any money
And the ATM should say there are insufficient funds
And the account balance should remain $10
Each scenario is an executable specification. Tools like SpecFlow and Gherkin can run these directly as acceptance tests. The requirement and the test are the same artefact. There’s no translation step where meaning gets lost.
Where UML still helps
BDD stories describe behaviour well. They don’t describe structure, layout, or data types. That’s where selective use of UML remains valuable—not as a replacement for stories, but as a supplement.
A mockup or wireframe attached to a story gives the UI requirement a concrete anchor. A simple sequence diagram can clarify the interaction between services when the Given/When/Then prose starts to feel ambiguous. Data type specifications prevent the perennial argument about what “date” means—UTC? Local? Which format?
The combination is deliberately minimal: one story with acceptance scenarios, plus whatever visual artefacts remove the remaining ambiguity. Not a full UML model. Not a 40-page specification document. Just enough.
What this changes in practice
When requirements are written in this form, estimation becomes more honest. You can count scenarios and use them as a basis for effort forecasting. The testing team participates from the start because the acceptance criteria are already test cases—they don’t need to be reverse-engineered from a requirements document after the fact. The client can read and challenge each scenario before development begins, which is the closest thing to a genuine review that most projects ever see.
Dan North described BDD as a technique for having better conversations about software. The format is almost beside the point. What matters is that requirements become precise enough to be falsifiable—and therefore worth writing down.
The tools have matured considerably since this was written. nBehave evolved into SpecFlow; Cucumber and Gherkin became standard in the Ruby and JVM ecosystems. But the underlying insight hasn’t changed: if a stakeholder can’t validate a requirement before you build it, you’re specifying the wrong things in the wrong way.