User Story is Worthless, Behavior is What We Need

Introduction

User Story is suitable for describing what user needs, but not what user does and how system reacts to user actions within different contexts. It basically gives product team a way to quantify their output and let their boss know that they are doing their job. As a developer, you can't write code from user stories because you have no clue on what is the sequence of user actions and system reactions, what are the validations, what APIs to call and so on. As a QA, you can't test the software from user stories because it does not capture the context, the sequence of events, all possible system reactions. User stories add little value to dev lifecycle. It only helps product team understand how much work they have to do eventually and it helps finance team get a view on how much money people are talking about. But to UI designers, solution designers, developers, they are nothing but blobs of highly imprecise statements that leave room for hundreds of questions to be answered. The absence of “Context” and “Cause and Effect”, and the imprecise way of saying “As a...I want... so that...” leaves room for so many misinterpretations that there’s no way development team can produce software from just user stories without spending significant time all over again analysing the user stories. Software, and the universe eventually, is all about Cause and Effect. The Cause and Effect is not described in a user story.

Unlike user stories, the “Behavior” suggested by Behavior Driven Development (BDD) is a much better approach because the format of a behavior (Given context, When event, Then outcome), when used correctly, lets you think in terms of sequence of events, where the context, event and outcome are captured for each and every action user or system does, and thus works as a definite spec for designing the UI and architecture. It follows the Cause and Effect model, thus it can explain how the world (or your software) works. It can be so precise that sometimes a behavior works as a guideline for a developer to write a single function! Not just the developers, even the QA team can clearly capture what action they need to perform and how the system should respond. However, to get the real fruit out of behaviors, you need to write them properly, following the right format. So, let me give you some examples on how you can write good behaviors for UI, business layer, services and even functions and thus eliminate repeated requirement analysis that usually happens throughout the user-story driven development lifecycle.

If you can force product managers to be 10% more precise in defining the requirements before passing it down the life-cycle, then you can save almost 30% of the total waste cost throughout the development life-cycle by saving time and cost in post analysis discussions, documentation and revisions.

User Stories to Behaviors

If you still live in the imperfect world where you get user stories dumped on your desk and you have to produce code from it, you need to learn to convert user stories into behaviors. Here’s an example:

As an anonymous user, I want to login on the homepage,
so that I can access my account details.

The above user story leaves the door for many interpretations. Give the above user story to a developer and then see how many round trips it takes between developer and product team and eventually between developer and QA to get this shipped to production. How does user login on the homepage? By going to a login page or the login box is embedded on the homepage? Is username in email address format or free form text? What do we show when the username is wrong or password is wrong?

So, you have to back this user story with acceptance criteria that will answer these questions:

Acceptance Criteria

Homepage must show a login box

System must validate username and password

Username must be in email address format

Password must be 6 characters and 1 numeric

System must show the dashboard when username and password is correct

System must show error if the username and password is entered wrong

First, you need to write some acceptance criteria to describe the environment user is in. You have to describe there’s a login box, it has username and password. Then you have to describe some user actions. How does user enter the username and password. Then you have to describe the system’s behavior how it reacts. All these are put as acceptance criteria as Assertive Statements that must result in True/False. This is a ridiculous way of describing user actions and system reaction to those actions. Software (and the universe) is all about Cause and Effect. This Cause and Effect is totally missing from user story.

If you convert this user story to behavior, it will look like this:

Given an anonymous user who has registered before and is on the homepage login box,
When user enters username and password on the login box and
clicks Login button or hits enter,
Then it should validate the username and password and
redirect user to the dashboard if the account is valid,
and it should show invalid username and password inside the login box
when the credentials are incorrect,
and it should update the last login datetime for the user in database.

Here you see the context (e.g., anonymous user, on homepage) is clearly separated and explained in the “Given” block, unlike user stories where the context is spread in some random order in acceptance criteria. Then the user actions are clearly explained in the “When” block, unlike user stories where the user’s action is partly described in “I want to...” part and then partially described in some of the acceptance criteria that you need to figure out yourself. The outcome, both positive and negatives are described in “Then” block in the behavior, which is equivalent to user story’s “So that...” and accompanying acceptance criteria. As you see, in one behavior statement, you can precisely define the environment or context user is in before performing the action, then user performing the action and then the system reactions to the action. The past, the present and the future sequence is clearly followed in a behavior.

Behaviors for the UI

Behaviors is a great way to describe UI requirements since it clearly captures the sequence of user actions and all possible system reactions. For example:

Given an account holder with some outstanding payments and direct debits setup,
When user goes to the Account Details page by clicking the link on the header area,
Then it should show the users’ account numbers and balances in a grid view,
and it should show balance in red if it’s a negative balance,
and it should show a list of outstanding payments in red,
and it should show a list of direct debits setup in a grid.

Give this behavior to a developer and the developer will scream with joy and produce beautiful code out of this. Compared to this behavior if you give the equivalent user story:

As an account holder, I want to go to Account Details page
so that I can see my accounts and their balances,
my outstanding payments and direct debits.

Acceptance Criteria

The account holder already has some outstanding payments.

The account holder already has some direct debits configured.

A grid view shows the account numbers and balances.

Negative balance must be in red.

A list shows outstanding payments in red.

A grid shows direct debits, if any.

It takes a lot more sentences to describe the same behavior. Moreover, the first two acceptance criteria, which describes the context, aren't really acceptance criteria. Since there’s no other way to put context in the user story, it has to be put somewhere on the acceptance criteria. Finally, there’s no sequence of events happening. It does not say how user goes to the accounts details page.

I use behavior to describe the UI requirements in my open source project Dropthings. It’s a Web 2.0 start page that renders widgets and allows you to customize the widgets. I can define the first user visit behavior in this way:

Given a new user,
When user visits the homepage,
Then it should show the default widgets.

I can then use this exact same behavior to write test code that automates browser, simulates the user actions and verifies the expectations.

The above test is written using xUnit, Subspec (xUnit extension) and WatiN. You can find hundreds of such tests in the project that shows you how you can use behavior to define the UI and then write code that automates browser, simulates real user actions and checks the output on the browser to find out if the behavior is satisfied. Dropthings is an AJAX web site. The test codes are rich in AJAX tricks and tips and should help you understand how to automated UI testing.

Behaviors for Services

You can use the behavior format to clearly define what input and output you expect from a service. For example:

Given an account holder with some outstanding payments and direct debit setup,
When GetAccountDetails method of AccountService is called with the account holder’s ID
Then it should return the account summary containing account names and balances,
and it should return an array of overdue payments,
and it should return an array of direct debits.

Now if you had to define this as a user story, oh boy:

As the Account Details page, I want to call GetAccountDetails of AccountService so that
I can get the account summary, overdue payments and direct debits.

In fact, it’s totally wrong. There’s no “user” here that will use the user story format. You have no choice but to use some other approach to convey such requirements to distributed component development teams. And the best approach is to use such behaviors to describe the behavior of the components.

Behaviors for Business Components

Just like services, you can describe behavior for Business Components. For example:

Given a user who has accounts with the bank,
When LoginManager.Login is called with user’s username and password,
Then it should return true if the username and password is valid
by calling Active Directory API,
and it should update the last login date time of the user in Audit database,
and it should throw exception if the username and password is wrong.

If you hand over this behavior to a developer, the developer can write the business components in his/her sleep. It does not need further discussion. It does not require some UML diagram that shows who’s calling who. It’s a super fast way to get requirements communicated to the developers. Moreover, if you are writing unit tests, then you can use this exact behavior to produce unit tests.

Here’s an example of creating a business layer component using a behavior:

The above code might look like a lot of code, but the point I am trying to make is you can produce business layer components out of behavior and you can test them using the same behavior.

Behaviors for Data Access Layer

You can even define behaviors for your database just like the way you do for services and business layer. If you have some SP that does some complex job, you can use the behavior format to define what the SP should do. For example:

Given a user in the aspnet_users table,
When AuthenticateUser is SP is called with the user’s loweredusername and password,
Then it should query the aspnet_users table to find a match,
and it should compare the password with the selected row in a case sensitive way,
and it should return the aspnet_user row if the username and
password matches successfully,
and it should return nothing if there’s no match.

Once you define the behavior this way, you can write the SP from it and then you can use some unit test tool to test the SP.

Behaviors for Functions!

If you have a function that does more than a trivial job, then you should use a behavior to explain what the function should do. For example:

Given a file in a local folder
When File.ReadAllLines is called with the file’s full path,
Then it should open the file and read all the content and return a string array,
and it should throw InvalidArgumentException if the path is wrong,
and it should return a null array if the file is zero length file,
and it should throw InvalidArgumentException if the path is a UNC or URL,

The above behavior is invaluable for writing unit tests. Once you get the function coded as per the behavior, then you can easily write a unit test for the function.

Again, here’s an example how I write behavior to explain what a particular function should do:

Here the behavior is explaining what GetTab function of TabRepository should do. I can then produce a unit test and use mocking frameworks like Moq to write a unit test for the function.

Conclusion

Behavior is an all-rounder solution to specify requirements for UI, services, business component, database, utility libraries and even for complex functions. The format encourages the requirement to be described in a precise way and leaves little room for confusion, when followed properly. Compared to user stories which can only explain user intentions, if behavior is used throughout the development lifecycle, it can greatly reduce repeated requirement analysis effort and can make the communication between product, design, development and QA team much more effective. If you can force product owners to be 10% more precise in defining the requirements, then you can save almost 30% of the total waste cost throughout the development life-cycle by saving time and cost in post analysis discussions, documentation and revisions.

Comments and Discussions

In your conclusion you state "If you can force product owners to be 10% more precise in defining the requirements, then you can save almost 30% of the total waste cost throughout the development life-cycle..." Do you have statistical data to support this assertion?

The first biggie is that the author doesn't seem to have grasped what user stories are, or what they are for. When you're first talking about required behaviour (yes, they ARE for describing behaviour) with your customer, they usually act as conversation placeholders, so they might be quite brief, and are normally of the form

As a <type of user>I want <to do something - ooh look! Behaviour!!>So that <some business benefit accrues>

Some people rearrange the order and wording somewhat.

Before you get to implement the story, you'll want to have a more detailed conversation with your customer to generate a more detailed description of the feature. This description is normally captured in scenarios (aka acceptance criteria) which often take the form

Given <something>When <something happens>Then <this is the result>

So the other big thing the author has failed to grasp is that scenarios/acceptance criteria ARE PART OF USER STORIES.

As an aside, I think his example scenarios are poor too. This is not a good sentence to find in a scenario:

When GetAccountDetails method of AccountService is called with the account holder’s ID

As I have iterated many times in the article, you eventually do the work to nail down the requirement at details I have demonstrated here. You just do it in several iterations and waste time and produce unnecessary intermediate excel sheets. My point is: Do it right first time. Stop producing intermediate waste. Produce something on the first attempt that goes through the end of the development life cycle and satisfies all stakeholeders (designer, dev, QA, deployment mgr)

This requires mind set change. And I do not expect everyone to do it.

But I have certainly seen the benefit of doing this mind set change and having the courage to tell your customers upfront that we need all the details in behavior format, otherwise we can't deliver. When customers are forced to think at such level, they start second guessing the value of their requirements, they realize solutions are too complicated, they realize customer will get confused from the features/changes and so on. This opens their eyes, makes them see end to end and helps them take right decision early enough in the cycles. Saves waste.

On the point where you mentioned I said acceptance criteria aren't part of stories: you are wrong. My point specifically was that to make a user story complete you must have the acceptance criteria with the stories. Without the acceptance criteria, a user story is incomplete, useless. Then I mentioned the problem with ACs. They aren't coherent, don't maintain sequence of action etc etc.

I'm not sure where the comment about the iterations and intermediate Excel spreadsheets comes from.

You should indeed try and reduce the amount of churn over requirements, or features, as the agile world prefers to call them. So you should normally leave full working out of the details until the last responsible moment. Doing too much work upfront will guarantee rework as requirements/features always change over the course of a project.

If your point is to say "that to make a user story complete you must have the acceptance criteria with the stories" then you need to change your first sentence (at the very least). You say :

"User Story is suitable for describing what user needs, but not what user does and how system reacts to user actions within different contexts."

User stories ARE about what the user does and how the system reacts. They are also about what the value is to the customer to be able to do whatever it is.

A user story is incomplete without scenarios/acceptance criteria/examples/etc. That's fine for when the story is in the backlog, but you have to work out the details eventually.

If you are having the problems you describe with scenarios then IME that's due to any or all of these reasons:

1. You have a bad user story, normally because a DEVELOPER story has been captured, not a USER story. The phrase "As a user" or something equally vague is a hint that has occurred, I believe. In my current company I see that a lot - they have not been sufficiently clear what role the "user" has. If you don't know then you can't really determine business value of the story, IMO.

2. The scenarios are too implementation based. Your examples are suffering from this problem, IMO. They seem to have been written from a developers perspective, not from the perspective of a user trying to get something done.

3. Putting too much in one scenario. Your login scenario is an example. There are at least 2 scenarios within it, one for a successful login and one when it is unsuccessful (I think there may be more actually, but that's a start).

There might also be a problem with the domain language being used, in that it is not actually shared between developers and customer - they have different ideas what things mean

1. I disgaree on your comment on the user story. It's not developer focused story, it's a user focused story.

As an account holder, I want to go to Account Details page so that I can see my accounts and their balances, my outstanding payments and direct debits.

There's nothing for developers here. If there was, it would have actually made it useful for designers and developers. It's from a pure user experience point of view.

2. The scenarios aren't implementation based. The above story does not tell you how you code it or actually where to get data from. It tells how user wants to work with the system. There's no point making it even more generic than it already is. Benefits no one.

3. You can certainly break positive and negative scenarios into multiple stories. No disagreement there. I just wanted to show an example.

Remember, there are many types of behaviors. There's behavior to describe how user acts. There's behavior to describe how systems act. There's behavior to describe how components act. User story has no types - it's always user focused. User story can't say how components act. But Behaviors can be of many types. If you think you have to define the full requirement from user to developer in a single behavior, you got the wrong idea.

I believe we will go in circles because we aren't on the same ground to exchange views. Your views are based on your "assumption" that it'll not work, where my views are based on positive results from practical implementation. I have done this, seen the difference and then spend a lot of time sharing the benefits via this article hoping it will help others. I believe you should deny this approach only when you have tried it and have failed. Let's not discourage people from something potentially beneficial when you have no result to back your claims.

Why don't you give this a try for couple of months? If it does not work for you, I would surely like to hear your story and see where things went wrong. It will then help others as well.

Remember that your story is the narrative (the "as a..." bit) and the scenarios. Both.

I think your narrative is developer focussed. You're already talking about the account details page. It's also more than one story, IMO. I think it ought to read more like:

As an account holderI want to see my account balancesSo that <insert reason here, eg I can see how much money I have to spend>

As an account holderI want to see my outstanding payments and direct debits

(You can leave out the motivation sometimes, BTW, although that can be perilous if you miss the business benefit)

Your scenarios mention implementation details all over the place. User stories (which is both the narrative and the scenarios, remember) are for conversations with your customer as well as for the developers. Does your customer really care if you query the aspusers table, or whatever?

You can sometimes use system stories instead of user stories, but they aren't all that common. When I was an architect on the iPlayer project we needed them, as large parts of the system have nothing to do with users.

You said:" Your views are based on your "assumption" that it'll not work"

Actually, that isn't my assumption at all (I don't see how you could think that it was, in fact). I use stories all the time, and have done for some years. I think they're a good way to capture features and to help plan work. What I am trying to do is to point out shortcomings in the way you are using them, and some errors in your article.

As an account holder, I want to go to Account Details page so that I can see my accounts and their balances, my outstanding payments and direct debits.

Omar, this seems to miss the boat by a significant margin.

My experience has shown that a better customer/user story will be written along the lines of:

fictitious_bob logs into the fictitious_system and navigates to the Account_Details feature. Once there, fictitious_bob reviews the balances of his accounts to ensure none of the accounts is operating in overdraft. fictitious_bob then checks that all the outstanding payments and Direct Debits (glossary reference goes here) can be met by the available funds. fictitious_bob benefits from this review because he is penalised by his bank for operating his accounts in overdraft.

Hope this helps in some small way, because customer stories are a far more powerful customer tool than almost any other in our arsenal. This is the only tool we have available that written by the customer in their own language. When well written it provides almost all of the acceptance criteria without significant extra effort.

As for the detailed "requirements", I agree with the comment about the agile philosophy "embrace the change" and this means leaving the detail until the last responsible moment. This limits significantly your exposure to rework (wasted effort) and allows your development efforts to flex when (NOT if) the business processes evolve.

This is a well-written, articulate and well-reasoned article describing how best to build an accurate specification of user requirements up-front.I can see the logic, and it certainly makes the work of the developers and QA easier and more predictable.However, it does seem to go against the agile mindset, and hark back to waterfall development.In my opinion, agile development produces better business results, because it accepts that the user doesn't necessarily know the best implementation of their requirements, and that a process of trial and review is necessary to iteratively progress to a good solution.Too often I've seen projects fail because they've wasted too long trying to generate the perfect capture of user requirements, and the requirements have invariably changed by the end of the project.I do like the examples of turning behaviours into tests, 'though.

My goodness. It's like you are working on my team! I think Scrum should be renamed Revenge of the Project Manager\Business Analyst for never getting credit. lol. Its the sloppiest most chaotic process I have ever been forced to be a part of.

My goodness. It's like you are working on my team! I think Scrum should be renamed Revenge of the Project Manager\Business Analyst for never getting credit. lol. Its the sloppiest most chaotic process I have ever been forced to be a part of.

I would have given you a higher number, but user stories are not "useless". Stories are placeholders for the conversations that take place later to reveal the desired behaviors. Stories without the details/behaviors should still be in the backlog not in the iteration.

The problems that I have/still see today are that stories are deemed "ready" when they get to a certain threshold. Sometimes it can be something stupid like filling in the blanks of a template in Word. But you are correct the desired behaviors are necessary to start development. Too many times those behaviors are left up to the developer.

At first I got the impression that it is comparison of two brief(user story) and detail (behavior) description of the feature thus comparison of two things which are not comparable. But, it is very different to writeAs a new user, I want to visit a home page so that I can see the default widgets.OrGiven a new user, When user visits the homepage, Then it should show the default widgets.The amount of words is more or less the same in both cases but the information that the reader learns is bigger when using given-when-then syntax because there is clearly written “sequence of causes” whereas in user stories no. User stories (or in general structured feature description) in its present format came to industry because the end user needed something that she could understand on one hand. Additionally, it had to be brief on order not to get lost in terms and flow.

Given-when-then syntax is both a) brief and b) descriptive. And for all, it can be simply converted into tests. I would suggest to visit SpecFlow that uses more friendly ideas mainly for writing tests based on behavior.

Nah it would be unfair to compare a single line user story with a detailed multiline behavior. That's not what I did. Take a look at the acceptance criteria. Remember, a user story is worthless without acceptance criteria. Devs don't know what're the expectation. QA don't know what to test for. Without AT, user story is meaningless.

When you put the user story with the acceptance criteria I have shown, then it looks like this:

As an anonymous user, I want to login on the homepage, so that I can access my account details.* Homepage must show a login box.* System must validate username and password.* Username must be in email address format.* Password must be 6 characters and 1 numeric.* System must show the dashboard when username and password is correct.* System must show error if the username and password is entered wrong.

Omar, I did not argue against your attitude. In general I vote for behaviors instead of user stories. Behavior can describe end-user intentions in clear format. Hovewer, user stories are high-level descriptions of software features, they often cover several scenarios. Given-when-then syntax by nature always covers only one scenario. User story describes high-level image of the feature. It can be missleading to compare the two.

I really appreciate your nice article because it can inspire a lot of discussions how to describe business requirements to developers as simply as possible.

Given an anonymous user who has registered before and is on the homepage login box,
When user enters username and password on the login box and clicks Login button or hits enter,
Then it should validate the username and password and redirect user to the dashboard if the account is valid,
and it should show invalid username and password inside the login box when the credentials are incorrect,
and it should update the last login datetime for the user in database.

But, in order to do it correct, IMHO you should actually convert this into multiple Scenarios, i.e.

Story Anonymous user logs in
As an anonymous user
I should be able to login
So I can see my history and other specifics forthis site...
Given the current user is an anonymous user
and the current page is the homepage
Scenario the user logs in with a valid account and a valid password
Given the user enters a valid username
and the user enters a valid password
When the user logs in
Then ....
Scenario the user logs in with an invalid account
Scenario the user logs in with a valid account and an invalid password

etc...

I also agree on the ui design comment; in my opinion prototype ui design and Specs should be created together...(FYI, I also published an article on this on my blog[^])

You are right. We can certainly break it into multiple behaviors. My personal preference is to have all the outcomes from the same action (When...) within the same context (Given...) in a single behavior. Thus I put several lines in the Then... block to capture all positive and negative outcomes.

I think that this article is probably most suitable for those teams who are currently adopting agile. The problems that you are describing however, feel to me, very much like those of a development team in either the forming or storming stages of team development. If you step back a bit and take into account the experiences of many "newer" agile teams as a whole, you will realize that the problems that you are describing are in no way unique, and are in fact something experienced by most agile teams in the process of tailoring the overall system to meet their specific needs. (As prescribed by the methodology itself)

That being said, you need to take into account that the agile philosophy itself both welcomes and promotes the tailoring of the predefined processes, and as such this article is but one of many ways to flesh out the process itself into something more relevant to your own current circumstance.

So at this point let me surmise by saying that although I think your article offers both a unique point of view and some rock solid, well thought out ways to get there, I will only take from this what is applicable to my own current situation. (Which at this point is a fair amount!) And apply it to the areas in my current process where I can see that your advice would benefit my team as a whole.

Again that being said, very good article, relevant at least to myself and my team. If I could offer one suggestion, it would be that you have this article edited/moderated by someone whose first language is English, as this would do a lot for the overall legibility of the article.