AAA Toolbox: Acceptance Criteria

Esse é um post de uma série que eu compartilhei internamente na ThoughtWorks uns anos atrás. Eu escrevi em inglês, então republico assim, mas se a série acabar sendo bem popular, eu prometo traduzir tudo.

Stories are a key artefact of agile business analysis, but in order to complete the validation loop, it is useful to describe what changes in the system are expected after the story is played. Stories in cards can be quite abstract and, therefore, hard to verify if the corresponding code does what is expected out of it. Instead, an analyst can write scenarios that describe the expected behaviour.

Mike Cohn called these scenarios "acceptance tests", and suggested using one-liners to describe the tests that should be performed. Dan North came up with the concept of Behaviour Driven Development, and as part of it, the standard format for scenarios in user stories. Much like the As a... I want to... So that... model, he proposed a "Given... When... Then..." template for writing acceptance tests and called them Acceptance Criteria. The "Given" part is used to set the stage (i.e.: describe the initial state of the pertinent variables); the "When" part to describe the event that triggers a change in the system covered in the story; and the "Then" bit to describe what is the perceived change in the system after the triggering event occurred, given the initial state of the system. For instance:

Given the user is on the "place car reservation" page

and the "customer name" field is not empty

When user follows the "complete reservation" link

Then user is directed to "car reservation confirmation" page

Other acceptance criteria for this story could cover what happens if the customer name field is empty, or what can be seen in the confirmation page. Acceptance criteria can be bound to implementation a lot more than stories should be. Ultimately, they should describe everything that is expected of the story. Analysts should make an effort to guarantee that acceptance criteria are not missed (by performing edge case analysis, reviewing with the product owner or other methods), as missed acceptance criteria will not be tested, therefore, even if implemented, cannot be guaranteed to work after changes in code.

Stories normally have several acceptance criteria. These acceptance criteria should be as atomic and unambiguous as possible. It is very unlikely that an "or" will be used in an acceptance criteria. In most cases where it would make sense to use it, it is advisable to split these conditions in multiple acceptance criteria. Similarly, "and" connectors in the "When" and "Then" clauses usually indicate that the acceptance criteria could be re-written or broken down. Of course, these are only smells that something is off and shouldn't be considered hard and fast rules. Ultimately, the acceptance criteria style should be agreed among the team based on the type of automated test being used.

AAA Toolbox: As a... I want to... So that...

Esse é um post de uma série que eu compartilhei internamente na ThoughtWorks uns anos atrás. Eu escrevi em inglês, então republico assim, mas se a série acabar sendo bem popular, eu prometo traduzir tudo.

Stories can be tricky things to write. You have to make them small enough, but also sensible enough to get some business value out of them. Most importantly, they need to be easy to recall at a glance after an initial conversation about them has been had.

There are a few questions that people normally ask before doing anything:

  • What am I doing?
  • Why am I doing it?
  • Who am I doing it for?

When using user stories, it is advisable to specify what needs to be done in a way that does not force developers to implement a sub-optimal solution just because a specific one is written in a card. In the other hand, developers working on larger stories can, over time, loose sight of the purpose of a story and implement something that doesn't fulfil the underlying goal of a story or ignores the needs of the target audience. Probably the best place to keep that information in order to avoid loosing sight of those key questions of a user story, is in the story card itself!

Years ago, a company called Connextra was using a standard template that addresses just that. Mike Cohn mentioned it in his book, and it became the de facto standard for writing user stories. Here's how Mike puts it:

As a (role) I want (function) so that (business value)

For example:

As a business traveller, I want to book a mid-size car in Newark Airport for tomorrow so that I can be sure a car will be available for me on arrival

This model forces the writer to think about the audience of a given functionality and the value it should fulfil. This way it is easier to maintain the focus on the most important questions and make the conversation revolve around it. Developers will have greater insight on what is important once they know the business value the story aims to provide; Quality Analysts can consider the skills set of the audience and how well rounded a story needs to be; Business Analysts may challenge the product owner when he or she prioritises stories whose business value is not aligned with projects objectives; and so on. In the example above, "business traveller" indicates a user that does this operation frequently, while the business value highlights the importance of the reservation being a guarantee of service, implying that the booking transaction must be committed as part of this story. Note that the story defines values for all major attributes of the reservation. Additional stories would be required to allow the user to change the parameters, check availability and process payment.

Story writers have to keep in mind that, even though this format helps at least putting some thought to the interested parties and business goals of a given story, it is not replacement for conversation and any template is only as good as he information you fill it with. The most important thing will always be discussing the story with other team members. Frequently, these discussions can reveal gaps in understanding or in the story itself and it is important that this feedback makes its way into the story.

I just had to use this image from Rachel Davies. I hope it is Creative Commons.

AAA Toolbox: Story Slicing

Esse é um post de uma série que eu compartilhei internamente na ThoughtWorks uns anos atrás. Eu escrevi em inglês, então republico assim, mas se a série acabar sendo bem popular, eu prometo traduzir tudo.

When writing user stories, a business analyst should strive to write them in a way that an incremental improvement will be available to the user after the story is completed. This means that things like "save 'order' object to the database" or "place all the fields of a form on the screen" are generally not good stories. These examples represent work divided in layers (a data access layer, the web front end, etc.) and, therefore, do not provide the full implementation of a given improvement until all bits are complete.

When divvying up stories, we should think of the way we slice a cake: a good slice should cut trough all the layers. This would include front end work, functional testing, validation, data persistence, performance testing and everything else necessary to present the user with a valuable piece of functionality. It is easier said than done! Many times it is hard to pin down beforehand which bits of functionality are essential to deliver business value, and frequently some bits are vital to more than one story, making it hard to know when to implement it.

Some people have offered patterns to do it (for example, here and here). They recommend splitting based on such aspects as operations (e.g.: CRUD - create, retrieve, update, delete), workflow steps (e.g.: each page of a wizard), business rules variation (e.g.: progressively adding flexibility or constraints to an action), major effort (e.g.: bundle all other variations together after the first of many similar features is implemented), data entry methods (e.g.: progressively fancier UI), platform support (e.g.: different mobile OS, older browsers), among others.

These are helpful suggestions, still, in may cases, they don't seem to work! Business value cannot be realised without some of the steps of a workflow; Grouping similar stories creates dependency on that one chosen story, which cannot be de-scoped without causing havoc to your estimations; Data entry assumed simple proves a nightmare to stabilise; each operation is too complex to implement as a story; Progressive enhancements generate a chain of dependencies between stories; And so on... Trying to accommodate all this conflicting demands can end up pushing an analyst to settle with stories that are too big or don't cut that proverbial slices trough al layers.

I've come to the conclusion that more often than not, you have to settle for stories that are somewhat imperfect, still there are some guidelines that can help make the tough decisions:

  • Stories must be valuable, if there is no way to make the story small enough and keep the businesses value, keep the story as it is and break it down in tasks during development (for example, when creating a story to display an attribute on the screen, make sure to include minimum functionality to set the value of the attribute if it hasn't been implemented elsewhere);
  • Identify the desired core of the functionality and make sure it slices all layers, so it is independent and the business value can be achieved as soon as it is played (for example, if you have to create a new page type, that can be browsed from different places on the site, have a story to create the page displaying real data and have it accessed from the address bar, leaving the references to the page across the site to separate stories);
  • As long as the system is not broken, covering edge cases and loose ends can be split into separate stories, this will give an opportunity for the business to de-prioritise stories (for example, if editing a record is a straightforward task, have it first with generic error messages, and enhance it in future stories with error detection or active help to the user);
  • Work closely with the developers to ensure that the proposed solution is complete and is the easiest technical solution. It is very easy overlook simple solutions to problems when trying to frame them in a generic-code agnostic language. It is common finding complex pieces of code available in open-source libraries. Sometimes hooking up to a well established library is easier than writing overly simplified solution;
  • Avoid loading stories with functionality that is not absolutely necessary to fulfil the goal (for example, adding a created date to a record that you don't care about the created date. If developers what to do it as part of the implementation is fine, but unless it is necessary to fulfil the goal, defer it until it becomes relevant);

Image adapted form original picture from Myrna Litt