Services | More Effective User Stories

GET STARTED!

User stories are one of the most important tools and technical design artifacts we have for documenting system requirements. Good, actionable user stories enable accurate, consistent estimation and efficient, complete delivery of high-quality software features without defects or the need for rework.

At a minimum, an actionable user story must:

  • Be written from the perspective of the system user who will benefit from the feature being specified,
  • Describe a single interaction between this user and the system,
  • Include objectively verifiable acceptance criteria, expressed as required preconditions and postconditions,
  • Anticipate the ways in which the interaction may not succeed and specify the ways that the system will react to these failures, and
  • Result in the delivery of automated tests (e.g. unit, regression, end-to-end, etc) along with the specified feature

Note: Objectively verifiable acceptance criteria leave no ambiguity or room for interpretation or disagreement. They either are or are not satisfied when the specified feature is demonstrated.


Note: User stories are not the only way that requirements can be expressed. Many requirements management tools provide other issue types like tasks, subtasks (think boxes that must be checked in order to complete a task or user story), bug/defect reports, etc.

This article focuses on user stories, which describe system interactions from an ​end-user perspective.

Tasks are typically used to describe work that do not directly involve an end user but that must be completed in order to enable or facilitate these end-user system interactions. I sometimes refer to Tasks as “engineering directives” like “Install and configure a PostgreSQL database server … ”.

Since this type of work doesn’t involve an end user, trying to express Tasks as User Stories often results in tortured constructs like “As a Full Stack developer, I want to install and configure a PostgreSQL database, so that​ system information can be stored and retrieved”.

Selecting the appropriate issue type will make requirements easier to express and to understand and deliver.


User stories are created iteratively with participation from the whole team and go through the following stages of development:

Element Example
Headline

Basic Location Management

Summary As a Business Owner,
I want to define and manage my business’s location, contact information, and operating hours, So that my business can be found easily by my customers and can better serve them.
Actionable
(Gherkin syntax, please see below for a Gherkin keyword summary)

Feature: Basic Location Management

As a Business Owner,
I want to define and manage my business’s location,
So that my business can be found easily by my customers and can better serve them.

# NOTE: See the “Location Management” screen mockup images attached below

# NOTE: See the “StreetAddress Entity-Relationship Diagram (ERD)” diagram attached below

Background:
Given I am currently logged in to the system, i.e. my browser has received a currently valid authentication token
And my business is represented by a record in the Organization database table
And I am currently on the “Manage Location” page for my business, conforming to the “Location Management” screen mockup image and specifications

Scenario: Successful Location Management
Given there are no records that represent my business location in the StreetAddress database table
When I submit (create/HTTP POST or update/HTTP PATCH) all required, valid StreetAddress data (e.g. StreetAddress1, StreetAddress2, CityName, StateId, CountryId, and PostalCode) to the system’s RESTful endpoint ‘example.com/api/v1/location’
Then this data is stored, along with system-generated and default data in a new or updated record in the StreetAddress database table, referencing my business record in the Organization database table
And a ‘201 Created’ or ‘200 Success’ HTTP response is returned
And the new or updated StreetAddress entity data is returned in valid JSON format
And the new or updated StreetAddress data is displayed on the “Manage Location” page for my business, conforming to the “Location Management” screen mockup image and specifications
And this interaction is logged using the system’s existing structured logging features (available on stdout and stderr streams)

Scenario: Unsuccessful Location Management Due to Invalid or Incomplete Data
Given there are no records that represent my business location in the StreetAddress database table
When I fail to submit (create/HTTP POST or update/HTTP PATCH) all required, valid StreetAddress data (e.g. StreetAddress1, StreetAddress2, CityName, StateId, CountryId, and PostalCode) to the system’s RESTful endpoint ‘example.com/api/v1/location’
Then the resulting exceptions are handled using the system’s existing exception handling features
And no database records are created or updated in the StreetAddress database table
And a ‘400 Bad Request’ HTTP response is returned
And no StreetAddress entity data is returned
And an “Invalid or Incomplete Data” error message is displayed on the “Manage Location” page for my business, conforming to the “Location Management” screen mockup image and specifications
And this interaction is logged using the system’s existing structured logging features (available on stdout and stderr streams)

Scenario: Unsuccessful Location Management Due to Internal Service Error
Given there are no records that represent my business location in the StreetAddress database table
When I submit (create/HTTP POST or update/HTTP PATCH) all required, valid StreetAddress data (e.g. StreetAddress1, StreetAddress2, CityName, StateId, CountryId, and PostalCode) to the system’s RESTful endpoint ‘example.com/api/v1/location’
Then one or more unrecoverable exceptions occur in the StreetAddress service
And the resulting exceptions are handled using the system’s existing exception handling features
And no database records are created in the StreetAddress database table
And a ‘500 Internal Server Error’ HTTP response is returned
And no StreetAddress entity data is returned
And a “Temporary Service Error” error message is displayed on the “Manage Location” page for my business, conforming to the “Location Management” screen mockup image and specifications
And this interaction is logged using the system’s existing structured logging features (available on stdout and stderr streams)

Scenario: Unsuccessful Location Management Due to Unavailable Service
Given there are no records that represent my business location in the StreetAddress database table
When I submit (create/HTTP POST or update/HTTP PATCH) all required, valid StreetAddress data (e.g. StreetAddress1, StreetAddress2, CityName, StateId, CountryId, and PostalCode) to the system’s RESTful endpoint ‘example.com/api/v1/location’
Then the StreetAddress service timeout is exceeded
And the resulting exceptions are handled using the system’s existing exception handling features
And no database records are created in the StreetAddress database table
And a ‘503 Service Unavailable’ HTTP response is returned
And no StreetAddress entity data is returned
And a “Service Timed Out” error message is displayed on the “Manage Location” page for my business, conforming to the “Location Management” screen mockup image and specifications
And this interaction is logged using the system’s existing structured logging features (available on stdout and stderr streams)

 

Note: An actionable user story is ready to be estimated, implemented, and delivered.

Note: In Jira, we would use the Headline text (“Basic Location Management”) in the User Story’s Summary field as well as using it as the Gherkin Feature, followed by the Summary, NOTEs, optional Background (preconditions that are common to each Scenario, and successful and unsuccessful Scenarios in the User Story’s Description field.

Gherkin is a formal syntax that uses keywords like:

  • Feature, where we can use our short, user story Headline, e.g. “Basic Location Management” and include our “As a /[Role or Persona] I want to /[Business Goal] So that /[Business Value to Be Delivered]” Summary expression of the story,
  • # (NOTEs or TODOs),
  • Background, shared Given preconditions that are common to each Scenario,
  • Scenario, a perfect place for describing the successful “happy” path and the “sad” paths or the ways the interaction may fail,
  • Given, this Scenario’s objectively verifiable preconditions,
  • When, this user story’s single user-system interaction,
  • Then, this Scenario’s objectively verifiable postconditions

The first one of these detailed, Gherkin syntax user stories can take a couple of hours to “evolve” from Headline to Summary to Actionable state, but can then be cloned and adapted in order to quickly and easily create other, similar stories.  Based on their clarity, completeness, and detail, stories like these can be successfully delivered by engineering team in days with zero defects and zero need for rework.

The case for clarity:

Organizations that attempt to develop with nothing more than a Headline (e.g. “Basic Location Management”) or Summary (e.g. “As a …”) user story in a rush to starting to code will:

  • Often grossly underestimate the effort and time required to deliver their stories,
  • Spend more time informally discussing and asking and answering questions about the story’s scope in multiple channels (e.g. chats, email, threaded comments, etc) than would have been invested simply thinking through and documenting the scope in a standard, structured format like Gherkin, which will delay story start and/or completion and will typically result in answers and decisions not being updated as objectively verifiable preconditions and postconditions in the story itself,
  • Waste a great deal of time disagreeing about whether or not a story is complete (or worse, simply declare victory and move on),
  • Suffer a high number of software defects or omissions that require rework, and
  • Ultimately disappoint their business stakeholders and the organizations they serve.

Aided by the structure of the Gherkin syntax, the process of thinking through and writing clear, consistent, considerate, complete, and actionable user stories with objectively verifiable precondition and postcondition acceptance criteria will serve us well.  It requires discipline and time, but the time and other precious resources saved in the effort will much more than pay for itself.

I’ve written about user story development best practices here, if you’re interested in learning more.

Let’s improve the way we document requirements in user stories reducing defects and rework!