Avoiding Overly Complex User Stories: Tips for Splitting Stories

Written by

If you’re working in an Agile project, you’re undoubtedly familiar with the difficulties of reviewing stories for their size and complexity. Many times, teams might feel content to say that a story looks good as soon as they feel that they might be able to complete the story within the iteration/sprint.

However, it's in the team’s best interest to spend a little more time and really assess if a story can be broken down and split into smaller stories. We’ll talk about some strategies and tips that we can leverage when trying to split stories.

Why are we splitting?

First, let's review why we might want to spend that extra time to split a story down to two or more stories.

The first and most important reason would be if the team wouldn’t be able to complete the story within the current iteration. But what if that wasn’t a factor? There are still many benefits to keeping stories as small as possible, one of which is to keep the code changes as small as possible. If we’re introducing code in smaller increments, it reduces the likelihood of introducing breaking changes. Keeping the pull request small also increases the likelihood of catching problems during code review. A smaller story also inherently means simpler acceptance criteria, and simpler acceptance criteria reduce the chances of requirements being missed or not being thoroughly tested. Smaller stories also mean that each stage of the process should be able to finish faster and thus stories are delivering value sooner.

What to keep in mind

There are plenty of guidelines and recommendations for stories but there’s one item in particular to stress: The story should be testable. And not just testable, but testable by the PO. It's very easy to introduce technical stories that might not be reviewable by the PO. Our goal is to deliver business value with each story. In other words, we’re slicing vertically instead of horizontally. A vertical slice includes all work to deliver a slice of functionality (in many cases this means including front-end and back-end work). A horizontal slice refers to work specific to a layer of the application. Also, it's important to note that not every story will benefit from splitting. This is an art and not a science. There are tradeoffs in many cases and you'll have to weigh the pros and cons. 

Tips for story splitting

Without further ado, here are some approaches to splitting stories:

Splitting by workflow

If a story describes multiple workflows then each workflow should get its own story. A workflow can be spotted by the different paths a user can take. In some cases it's directly related to the CRUD actions a user can take on an entity. 

Splitting by data or data source

Similar to splitting by workflow, when a story is working with multiple data sets or data sources then you should consider splitting that story so that each data source or data set gets its own story. Having different data sources can exponentially increase complexity in things like retrieval, data cleansing, data formatting and validation. 

Isolate variations

If a story describes variations in the story then we should isolate the variations and create a story for each. A variation can be described as a change in behavior under different conditions. 

Split by business rule

If multiple business rules are present then they can be extracted to different stories. Some business rules can’t be implemented in isolation, so some evaluation needs to be done to see if a particular business rule is independent of others. 

Split out optimization

If a story describes some minimal performance requirements you should split that performance requirement into a separate story. The idea is to get it working first then get it working faster later. 

Split by subsection

Are there clear subsections that can be identified? If they can be carved out independently then you can explore splitting out additional stories for these sections. 

Using placeholders

For stories that have a UI and data component (formatting, retrieval, etc.) that can’t be split by data or workflow, one strategy is to use placeholders. The premise is to be able to split a story that describes a UI displaying some piece of data into two stories: 

  • First story: A story focused on building the UI piece. We’ll use placeholder/fake data. PO verifies that the UI is accurate 
  • Second story: A story focused on the data component where you’ll retrieve/format and display the actual data. PO verifies that the data is accurate.

You might be tempted to just create a technical story to fetch and format the data, but using placeholders would allow for PO review. 

Creating an interim state

If none of the above strategies seem feasible then you may want to create an interim state for the app. The goal here would be to finish a subsection of the original requirements and bring the app to an interim state. We want to make progress on the story but we land at a point that isn’t described in the original story: we’re creating this interim state. The suggestion here is simply that we might need to think outside the box in terms of delivering a story—that we can possibly offer a detour that makes progress on the original requirement.

Create a technical story

The goal is always to slice stories vertically, but there are times when we need to perform a horizontal slice and get some foundational work done.

Create a spike

If all else fails then we might need to take a spike to do some discovery and documentation. The purpose of this would be to solve the hardest problems of the story and sort out any grey areas. With a game plan in place the story should be easier to complete. This really should be saved for special cases and used as a last resort. 

Here at FullStack Labs, we produce high-quality solutions for our clients that they love! If you like what I posted above and would like to join us, please visit our Careers page.

Frequently Asked Questions