Conversations about user stories focus on the behavior of a system, without regard for time, memory, etc. Other times, we have real-world constraints – quality attributes – that may not fit comfortably as stories: performance, memory, extensibility, etc.
Behaviors are functional, in the mathematical sense: “given these inputs, you get these outputs.” Perhaps you’ve seen Given-When-Then tests; they usually take that approach.
Non-functional is a catch-all term for everything else: performance, reliability, maintainability, usability, memory constraints, design constraints, etc. You’ll also hear these described as para-functional, “ilities” (since so many related terms end in those syllables), constraints, and quality attributes. (I tend to use the latter term.)
For example, a Ford Model T and a Tesla Model S both address the same core functions: speed up, slow down, turn, stop. But the Tesla has far higher quality than the T in many ways:
- 0-60 in 1.98 seconds vs. “how about we do 0-30 instead?”
- Higher reliability
- Ability to go up steep hills in a forward direction
In fact, I can only think of three things the T is better at:
- Price
- Using gas (better when charging stations aren’t around and for quick refill)
- Looking like a Model T
Once a certain level of functionality is reached, quality attributes drive our perception of value.
Crosscutting vs. Local
Broadly, we can think of quality attributes as being crosscutting (across many features) or local (focused on one area of behavior).
An example of a crosscutting, emergent concerns is memory usage. The total memory usage is affected by many things, not just one story. A local concern might be the performance of a single feature, e.g., return a query result within three seconds.
Describing Quality Attributes
Tom Gilb, in Competitive Engineering [see References], has the best treatment of quality attributes that I know of. He has broken down a variety of goals, and has “Language” to describe them.
I tend to use a lighter approach – a sentence with the target, e.g., “Query response time < 2 sec. 90% of the time, measured from when the user hits return until the screen updates.”
The key thing is to make sure the team agrees on the goal and what would be a valid test. But if your situation requires the formality, you certainly should use it.
Quality Attributes with Stories
How do you describe quality attributes? Local ones are easy: just add another bullet point to the card. Doing so may make the story harder to implement, and developers will have to do extra work to demonstrate that the desire is met.
For crosscutting concerns, I’ve seen a couple approaches.
First is to have baseline stories. These can be constraints that are true at the start, and kept true over time. When they can, wise teams automate and maintain tests for them, to avoid surprises.
Some examples:
- Use a combination of Java and SQL for all code [a design constraint, perhaps for compatibility or other reasons]
- Every update must be able to be reversed, leaving the database structure and contents as they started.
- Internationalize all user-visible text.
Not everything can be handled as a baseline. You might have new needs you didn’t know about at the start of the project, and now you need to catch up.
For example, suppose Java provides an important security update, but only for modern versions, and your system is on Java 5.
Or perhaps scaling hadn’t been an issue, but a sudden spike reveals that you need to handle twice as many concurrent requests.
For needs like these, you might have stories that don’t fit a typical user story template. That’s OK: skip the template and write a headline that works!
Splitting Quality Attributes
Crosscutting concerns may have a short headline but a large cost to implement.
I know three strategies:
- No Split – “Lock the doors for the next few months – no new stories until we get this conversion done”. However, many times, this approach turns into “Let’s put it off until we have time”, which easily becomes “Oops – we’re too late.”
- Piece-by-piece (incremental): In some cases, you can divide up the work, fixing one area at a time (and potentially releasing each improvement).
For example, you might be able to first address the 20% that accounts for 80% of all usage, then do the rest one area at a time. - Narrowing-in (iterative): Give yourself intermediate goals, closer and closer to the overall goal. If you’re lucky, you may find your overall goal is more than you really need.
For example, if you have a process that takes 26 hours to process 24 hours’ worth of date, you might first target 20 hours, then 12, then 6.
Conclusion
Quality attributes describe the concerns that aren’t about the functional behavior of a system. They may be crosscutting or local.
You need to find ways to express these (more or less formally) so that all understand and agree on what you mean.
Local concerns can be part of a story. Crosscutting concerns may take the form of baseline stories (standing constraints), or new stories. Either way, you need to test.
When you need to “split” quality attributes, you may be able to take a piece-by-piece approach (incremental), or a narrowing-in approach (iterative).
Behavior is important, but quality attributes are a key differentiator of perceived quality.
References
Gilb, Tom. Competitive Engineering. Elsevier, 2005.
“Stories” [tag], https://xp123.com/articles/tag/stories/