Requirements have gone from lengthy specifications that state “The system shall…” for dozens of pages, ad nauseam, to a single sentence story. But stories aren’t meant to capture all the details needed to build a feature, so where do those details come from?
Alistair Cockburn describes user stories as, “a promise for a conversation.” Stories move requirements from a written document to a conversation between the Product Owner and the development team. They aren’t meant to replace requirements, they’re meant to help create a context for requirements, which are then discovered by the Product Owner and development team working together.
This has several advantages. A NIST study found that more than half of all development effort is spent writing and interpreting written requirements, and more than half of all bugs in a system can be traced back to poor or inadequate requirements.
Turning requirements into discovery helps us build a better product. It keeps us focused on finding solutions throughout the development process instead of just following a plan. It helps us constantly ask if there’s a better way to do things, and that often leads us to better results.
But there’s a challenge to using stories. They speak in generalizations. For example: “As a moviegoer, I want to purchase tickets online so I can avoid lines at the theater.” This story tells me what is wanted, who it’s for, and why they want it, but it lacks specific details.
So how do we go from stories to code?
There is no straightforward answer to that question. A lot has been written on story breakdown but much less has been written on how to code a story incrementally.
One trick that I use when coding stories is to start with an example. Examples are concrete, so they’re understood in a different part of the brain than generalizations. They also help bring up different issues so we can understand a feature from different angles.
We think concretely, so working through simple examples can ferret out issues that I may not have noticed until I was in the middle of coding. Examples also let me get a strong sense of the feasibility of an idea before I get too deeply committed to a particular solution.
For me, examples are the middle ground between stories and code. That’s why I love the book, Specification by Example: How Successful Teams Deliver the Right Software by Gojko Adzic. This book discusses how to use examples effectively for specifying what behavior to build.
Rather than try to come up with exhaustive examples of a system, the approach that Gojko Adzic advocates is to find key examples that cover the main concepts. This keeps examples more general-purpose so they’re more straightforward to repurpose in the future.
Good examples, like good unit tests, should be as implementation independent as possible. They should cover the main cases but not be concerned with covering all exceptional paths. The result is a set of key examples that are easy to read and give you a sense of the essence of a system.