The Rocket Fuel of a Project – Good Acceptance Criteria

I had a manager once who would constantly harp on both the product team for not writing stories with good acceptance criteria and on the engineering team for accepting these “poorly written” stories. He would claim that his engineering team was the engine, and it would only perform as good as the fuel you gave it.

Better fuel makes things perform better, whether it’s high octane gas for your car or great acceptance criteria for your engineering team

If you’re familiar with Agile, then you’ve probably had the general story format of “As a [USER] I should be able to [DO SOMETHING] so that I can [ACCOMPLISH SOMETHING].” beaten in to you. It’s a great concept, and as a Scrum Master, I can say that it does work. Of course, you don’t have to take my word for it (even though I hope you will). Mike Cohn of Mountain Goat Software, one of the authorities on Agile and Scrum discusses the advantages of the As a User, I want User Story Template.

Here’s the one problem I have with using that format: Engineers get their hands on it. They bastardize it. They take it to be gospel. They use it to not have to think.

I’ve had engineers who would write system level stories with things like “As a System, the System should have Logging, so that the Developer has something to look at with things go wrong.” Gee, that’s nice. What are you trying to log? How will you access the logs? (which should really be another story quite honestly…) What sort of things do you mean by “go wrong?” And of course, my favorite bit, “As a System, the System should…” Is the web server actually sentient and have a concept of self? (Try and bend the process and I’ll pick anything and everything apart…)

Then there’s the individuals who just don’t want to follow the format. “Why?” they whine. “What’s wrong with just attaching a picture of the white board from the meeting we were all just in to the story? The devs who will build it are in there.” You should definitely add the picture. It’s an artifact to the process.  But don’t rely on it! Weeks could pass before the team gets to that particular story. A crucial team member could get hit by a bus or win the lottery. You need context to the story.

I’ve seen issues even following the format to the letter. This arises from the statement being too vague and the product owner expecting more than they wrote. The engineers take those vague statements as gospel, and then hide behind it as the story doesn’t pass, or ends up having three more stories written to clarify the original work. They use it as a crutch to not have to think about more than what was written and potentially not deliver greater value.  I once saw a story rejected because the statement was “As a User, I want to be able to log in and see what I have permission to see.” A little vague, but tolerable. The story was failed because of a different issue; the product owner didn’t like the error messages displayed if it was a failed login attempt. Funny, I didn’t see anything in the sentence regarding failed login attempts… You know what would have alleviated this issue? Acceptance Criteria.

By explicitly stating after the “As a User…” statement what the expected results would be this could have been avoided. Acceptance Criteria for the above log in story could be as follows:

  • The user will be able to enter their user ID (email) and password and select the button labelled “Login” to log in to the system.
  • If the user enters an incorrect ID and password combination they will be presented with the login screen and an error message above the fields stating “You have entered an invalid ID or password.”
  • When the use successfully logs in they should see content appropriate to their User Roles:
    • Standard users will see their dashboard with content they have subscribed to defaulting to the last 30 days ordered from newest to oldest
    • Staff will see the internal dashboard
    • Admins will see the internal dashboard augmented with extra tabs for user account management and subscription payment management

So how do you write good acceptance criteria?

Think of acceptance criteria as a helping guide for how you or someone else would test this work. No amount of detail should be spared on your road map of how to verify the story. In some cases it could be as detailed as an AAA TripTik (If you ever had a paper one made for you, you’ll know what I mean).  It often helps to draw out a flow chart or build out a spreadsheet of desired actions and possible outcomes. For the login example, the spreadsheet might look something like this:

Login Acceptance Criteria Example

PageURLActionExpected ResultData Needed
Login Page/loginLogin as a standard userStandard users will see their dashboard with content they have subscribed to defaulting to the last 30 days ordered from newest to oldestUser: standard@sample.com
Password: password
Login Page/loginLogin in as a staff userStaff will see the internal dashboardUser: staff@sample.com
Password: password
Login Page/loginLogin as a system adminAdmins will see the internal dashboard augmented with extra tabs for user account management and subscription payment managementUser: admin@sample.com
Password: password
Login Page/loginAttempt to log in as an invalid userUser is redirected to the login screen and is given an error message above the fields stating “You have entered an invalid ID or password.”User: baduser@sample.com
Password: badpassword

While this will often fall to a designated QA individual or team, not every organization is set up to have a dedicated QA group. Regardless of if you have QA available to you or not, be sure to write the acceptance criteria with enough detail that anyone in your organization could follow the steps. It will help with testing, and it will help with development. If you do have QA available, engage them to help you write Acceptance Criteria that will help all of you. They’ll have plenty of tips to give.

So back to the fuel… You can give your engineers basic requirements, or you can give requirements and acceptance criteria. One will act like 87 octane in a Corvette; you’ll get there, but there will probably be some sputtering and a few issues down the road. The other is going to be like putting in 93 octane in that same Corvette; it’s going to purr and give you much better performance in the end.

Patience. It Matters.

In this fast food, same day shipping, not even one hour photo processing anymore world we live in, change is expected to be visible immediately. However, just because you have put process changes in to effect, or wrote a few new tests for your code, doesn’t mean you’re going to see immediate results. Be patient with getting the results. That goes for both you not losing faith in your own work and for your superiors to understand (manage up!)

I’ll admit, I’m a bit of a speed demon. My leaden right foot has certainly gotten me into trouble a few times. But there’s one time where I’ve learned that patience is definitely worth it: heavy traffic. Over all the years of my commuting I’ve done a little experimenting. One week I’ll (safely) drive aggressively, lane change to the lane that’s moving just a little faster, hard stop and start, well… you know the drill. You’ve probably either done it yourself, or have seen others do it day after day on your own commutes. Other weeks I’d just pick a lane and relax; just go with the flow and not be impatient. Believe it or not, over a 30 mile commute, the difference in times was only about 5 minutes, but the difference in stress levels and blood pressure was significant. Thanks to a little patience on the road, I was more relaxed and productive in the office, and much happier once I was back home.

But enough of the psychology of having some patience on your commute… How does it relate to being an engineer or a manager?

A little while back I was talking shop with some old colleagues of mine. We commiserated over how bad some of the coding practices were at that old job. One thing we never were given time to do properly was write tests, and that bothered all of us to one degree or another. Since that job, he’s started his own development company, and has vowed that everything they produced would be done with proper TDD (Test Driven Development) and he always shoots for at least 80-90% test coverage. He said that in the end it paid off, as the tests did catch an introduced bug before they launched the new release of one project. Here’s the kicker: it took almost 18 months for the tests to actually fail. On the one hand, that’s awesome that his team was able to go bug free for that long. However, it also highlights where patience matters. They worked hard to follow their processes, which admittedly slowed them down from time to time, but were eventually rewarded by seeing their test work catch an issue before it affected a customer. Comparing that to the job we had both shared before where the tests didn’t catch anything in a month, so management insisted that we stop wasting time writing tests. That project ran for over three years, and never launched; partially because of the number of bugs which kept being introduced but never caught until after the fact.

Similarly, I recently held a position where I was asked to introduce new processes with the engineering team to try and speed up their delivery as well as reduce bugs and better schedule feature delivery. Before I arrived the best delivery times were often “sometime in next quarter.” It’s just a little hard to sell something to a customer on a promise of sometime in the next three months… I put processes in place, opened up communication, tracked down answers and issues (like a Scrum Master on his third pot of coffee). The problem is, old habits die hard, and change didn’t happen overnight the way my boss wanted it to. I explained that it takes time and showed data to back up the small progress which was made. I corrected course based off of the data, and off input from the engineering team. None of that mattered though, because I wasn’t performing the miracle of overnight perfection that my boss had in his mind. I wish him success, but I also wish him a smidgen of patience and a willingness to let things properly run their course to be able to judge success. Some changes really are a long game, and need the patience and strength to stay fully committed to them.

As an engineer, you’re selling yourself short if you’re not urging patience on your management. There’s nothing wrong with pushing back with a better solution that may take longer to implement. The challenge is how to explain it. You have to be able to explain that it may take an extra day, but the solution will provide even more value to the customer, stability to the system, preparation for the next feature, etc… to justify the time. Explain the reason for why you’re asking for patience. With a solid reason which ultimately positively impacts business, you run a better chance of getting the time and patience than just a “because I need the time to do it right” type answer. With each success after the request for patience, you’ll find management more receptive to the next time you ask for it. If you’re lucky enough, you’ll find that management even starts asking or offering the time for a better solution. Of course, you’ll just have to be patient for that to happen…

It’s also critical to be self-aware when solving a problem. Don’t just rush through to be able to grab the next task. Have a little self-patience and ensure that the code is done right. Double check your work. Make sure you’ve covered the odd edge cases you thought of while working on it. That patience in your own work will result in less mistakes in the long run, and even deeper tests which will cover more detail.  Of course, then you’ve got to be patient once more for those tests to catch something. But you already knew that, right?

In the meantime, I’m off to exercise that lead foot of mine. Patience is great, but sometimes you still want to go fast…