1-416-800-0918
Thought leadership / blogs

An In-Depth Guide to Writing Technical User Stories

Written by: TribalScale's Product Management Experts

Building the Right Thing, and Building the Thing Right

With technical products, deciding what needs to be done is just the first step. Figuring out how to actually define that “what” is a difficult and ongoing challenge for product managers. Fortunately, like the development cycle, feature specification itself is an iterative process, and it’s owned by the entire team.

If you’re building an API, middleware, or any kind of backend product, you’ll likely face these (additional) challenges when defining requirements:

  • Features are often tightly coupled and co-dependent
  • Features touch multiple parts of the system (or systems)
  • Small changes can have far-reaching impact — lots of nuances to consider
  • Hard to keep end-user value top of mind or explain value to stakeholders
  • Unfamiliar jargon: highly technical or vendor-specific terms

As such, building a more technical product requires substantial preparation and a lot of communication. But what does that look like, exactly?

 

AI generated image of product managers collaborating on writing user stories

AI generated image created with Bing's Image Creator

 

User Stories vs. Use Cases

First, you need to decide how you’re going to define what your product does.

User stories are widely regarded as the best way to capture feature requirements in agile development. They were first introduced by the Extreme Programming (XP) framework in 1998, which stated that project scope is defined “with user stories, which are like use cases”. User stories begin as a simple sentence which can fit on a card, describing an action/goal and its benefit to the user. These stories are designed to invoke conversations between team members, where details are added as the functionality is built.

 

Read our previous blog to dive deeper into what user stories are, why they are important, and the goals of crafting great user stories. 


Use cases, on the other hand, provide a more detailed description of the interaction between a user (role) and the system from the beginning. These are more popular in technical projects as they capture the preconditions, triggers, and responses of the system to all the possible paths (successful and unsuccessful) that could occur when the user performs an action — which can make engineers’ lives a lot easier.

The debate on using user stories vs. use cases continues today: some even argue that the two converge as they move from conversation to confirmation. As long as it works for you and your team, it shouldn’t matter what you use. Personally, we like to use a hybrid approach: leveraging use case thinking to help discover what stories need to be written.

 

What Makes a Good Story?

Stories can make or break a project, especially a highly technical one. Good stories are:

  • Independent (can be built separately to other stories)
  • Negotiable (requirements can be adapted)
  • Valuable (provides benefit to the end-user)
  • Estimable (to reasonable accuracy)
  • Small (can be built within one iteration)
  • Testable (can be verified by QA)

So how do we get from high-level product feature ideas to these INVEST-worthy stories?

 

First, Establish a Hierarchy

Projects can quickly become overwhelmingly complex and it can be difficult to find and keep track of tasks — creating a human-readable organization layer helps keep the relevant information easily accessible at all times.

We like to use epics to describe large chunks of system functionality, which are comprised of features that describe some kind of job to be done, which are in turn comprised of the user stories required to achieve that job. For example:

  • Epic: Ability to access on-demand content
  • Feature(s): Ability to find a podcast to listen to, and ability to subscribe to a podcast
  • Stories: Get list of podcasts, search for podcast, and filter for podcast by market or category

Others may prefer to do this differently. If your team prefers using labels, then do that.

 

Feature Slicing

Features should be sliced vertically, not horizontally, to break them into stories. That is, you should focus on end-to-end user value, and not by frontend tasks vs. backend tasks. A story should reflect the end-user’s action e.g., “be able to add a podcast to their favorites”, which could then comprise of frontend and backend elements contained within that story, like “add a favorites button to the UI” and “save the podcast id to the user’s account”. This applies to all types of projects, technical or not.

 

A diagram depicting feature slicing for user stories in product management

If your product is an API, then your stories will still reflect this vertical slicing — except the “frontend” action might instead be with reference to hitting an endpoint like `POST/favorites/podcasts`, instead of clicking a button that looks like x.

 

Stories Get Smaller Over time

As you work with your engineers and QA to better understand what should be done, stories can be broken into smaller and smaller chunks as the details and dependencies become apparent.

 

Diagram to depict how user stories get broken down into smaller and smaller chunks each time

You should consider breaking down a story if:

  • There are multiple unrelated acceptance criteria
  • Some elements are considered ‘nice to haves’
  • Team is struggling to estimate development effort
  • Story does not fit within a single iteration

 

How Small Is Too Small?

For example, to provide an end-user with the ability to search for a resource by typing in search terms, the acceptance criteria should cover these scenarios:

  • Single search term
  • Multiple search terms
  • Search + other query parameters
  • No matches found

The end-user doesn’t differentiate between “searching for one term” vs. “searching with multiple words”. To them, it’s just “searching”, so they can be combined in the same story. Separating these may lead to confusion during implementation, especially if different people are working on the stories.

However, different functions, like sorting vs. searching, should be broken out into separate stories.

 

Happy and Unhappy Paths

Use case-thinking is really helpful to ensure your stories cover all the possible paths, conditions, triggers, and outcomes, e.g., “the user performs a successful ‘create’ action”. If you're a big fan of the Checklist Manifesto, you can use this quick list as a reminder to consider the different types of paths which can be taken by the user (obviously, this can vary from product to product):

CRUD actions:

  • Create
  • Read
  • Update
  • Delete

 

WEESLD states:

  • Waiting
  • Empty
  • Error ← THIS IS VERY IMPORTANT
  • Success
  • Limits
  • Default Values

 

Configuration options (FSSPI):

  • Filtering (single parameter, multiple parameter)
  • Sorting (single parameter, multiple parameter)
  • Searching (single term, multiple term)
  • Pagination (page size, page number)
  • Include (what related information can also be returned in the response?)

 

At the most detailed level, we usually find you need at least one story per action-state-configuration permutation to completely define a feature e.g., “unsuccessful create” or “successful read with filtering applied”.

This approach can lead to needing multiple stories to properly define a feature: in addition to labelling, prefixes and consistent naming conventions can be used to find these more easily. Also, emojis are a fun way to quickly differentiate between happy path and unhappy path stories!

 

The Story Itself: Bringing It All Together

If an API is the product, then the routes, method, request, and response definitions are the business requirements. We've found writing stories in the Gherkin format (given, when, then) to be helpful since this accounts for pre-conditions, and offers an elegant means to describe different outcome paths:

Summary: As a {end user}, I should be able to {action}, so that I can {benefit}

Acceptance Criteria:

  • GIVEN: A {end user} is {doing the action} in the {app}
  • WHEN: The app hits the {endpoint route} endpoint with a valid request, containing {required request parameters}
  • THEN: The app should receive a status {code}
  • AND: In the response, the following information should be returned: {required response parameters}
  • Sample Request/Sample Response

 

Dev Notes/Resources: {any supporting notes here}

Testing Notes: {notes for QA, with examples if applicable}

As tempting as it may be: stories are not implementation instructions. Technical stories are supposed to describe what happens, not how it should be built — let the engineers find the best solution for this, and let them document this. Remember, no one likes to be told how to do their job.

 

Supporting Materials

To help ensure the right functionality is built and tested, stories should be supported by:

  • User workflow diagrams
  • Wireframes, design prototypes, high fidelity mocks
  • Customer feedback
  • Architecture diagrams, schema definitions, and technical documentation
  • Response matrices
  • Explanation of jargon (I always create and maintain a glossary)

 

Error Handling

Error handling is especially important for backend-heavy products where there is no UI available to prevent a user from going down an unsuccessful path. Responses should ideally contain at least the following information:

  • Error id (to help trace the specific instance of the error)
  • Transaction id (to help trace the workflow a user was performing, especially if there are multiple steps)
  • Status code (e.g., 400)
  • User-friendly message (e.g., “Please log in and try again.”)
  • Error key (more technical information for debugging purposes e.g., FACEBOOK_ACCESS_EXPIRED)

Using a response matrix is a quick and easy way to specify these requirements (for happy and unhappy paths), and should be referenced in the story itself. For example:

 

Example of a response matrix

 

Story Maintenance

Stories should be continually updated with relevant information by all members of the team. We do not believe that requirements should be left alone once they’ve been estimated — have you ever tried following a comment thread on a story? — as long as it is clearly indicated what the original expectations were, and what they are now (and why the changes were needed). If you need to re-estimate, then do so. If you are working in an agile fashion, you should be able to adapt to these changes in scope.

 

Refactoring Your Stories

Just like engineers refactor code to make it more efficient, your stories should also be refactored as the project progresses. A good product follows a consistent standard of requests and responses. Open standards like JSON API are a great place to look for inspiration, but make sure your users needs come first. Instead of re-defining the same behavior each time, identify these patterns, define your own spec and refer to it constantly.

 

General Conventions

What non-functional standards should be adhered to, and are consistent across the entire product? Think about:

  • Language Support (e.g., English only)
  • Parameter Specification (e.g., snake case, camel case etc.)
  • Data Formats (e.g., date is always YYYY/MM/DD etc.)
  • Names (e.g., routes always use plural form)

 

Functional Conventions

What can a user expect from each feature, functionally? Which behaviors are consistent, regardless of the path?

  • CRUD (e.g., do all endpoints support all methods of CRUD? Which ones? Why?)
  • WEESLD (e.g., how are empty or error states handled for all endpoints?)
  • Configuration options (e.g., do all endpoints support filtering? Pagination?)
  • Case Sensitivity (e.g., are all endpoints case insensitive?)
  • Encoding (e.g., do all endpoints expect parameters to be URI encoded?)

 

Summary

In agile development, user stories are your source of truth. They should contain enough information for your engineers to build the right feature, for QA to confidently and independently verify that the feature was built to specification, and for a business stakeholder to clearly and easily understand what the feature does. Technical projects are often subject to more nuance, and require more careful planning to account for the numerous different paths that can be taken. A combination of use case style thinking and user story based approaches can help you ensure all your bases are covered, while keeping the end-user benefit in mind.


 

TribalScale logo

 

At TribalScale, our product management team is at the heart of creating world-class digital products. By leveraging cutting-edge technologies and collaborating closely with our clients, we deliver solutions that not only meet but exceed expectations. Our commitment to excellence and user-centric approach sets us apart as a software development company that thrives in the fast-paced and ever-evolving digital landscape. 

Let's work together

Have questions about your next digital project, startup or TribalScale? Let’s work through it together.

OPTIONS TO CONNECT