Posts Tagged extreme programming
Scenario-Oriented vs. Rules-Oriented Acceptance Criteria
Posted by AntonyMarcano in Agile, BDD/ATDD, Business Analysis, Software Development, Software Testing, Uncategorized on October 2, 2011
Acceptance Criteria, Scenarios, Acceptance Tests are, in my experience, often a source of confusion.
Such confusion results in questions like the one asked of Rachel Davies recently, i.e. “When to write story tests” (sometimes also known as “Acceptance Tests” or in BDD parlance “Scenarios”).
In her answer, Rachel highlighted that:
“…acceptance criteria and example scenarios are a bit like the chicken and the egg – it’s not always clear which comes first so iterate!”
In that article, Rachel distinguishes between acceptance criteria and example scenarios by reference to Liz Keogh’s blog post on the subject of “Acceptance Criteria vs. Scenarios”:
“where she explains that acceptance criteria are general rules covering system behaviour from which executable examples (Scenarios) can be derived“
Seeing the acceptance criteria as rules and the scenarios as something else, is one way of looking at it. There’s another way too…
Instead of Acceptance Criteria that are rules and Acceptance Tests that are scenarios… I often find it useful to arrive at Acceptance Criteria that are scenarios, of which the Acceptance Tests are just a more detailed expression.
I.e. Scenario-Oriented Acceptance Criteria.
Expressing the Intent of the Story
Many teams I encounter, especially newer ones, place higher importance on the things we label “acceptance criteria” than on the things we label “acceptance tests” or “scenarios”.
By this I mean that, such a team might ultimately determine whether the intent of the story was fulfilled by evaluating the product against these rules-oriented criteria. Worse still, I’ve observed some teams also have:
- Overheads of checking that these rule-based criteria are fulfilled as well as the scenario-oriented acceptance tests
- Teams working in silos where BAs take sole responsibility of criteria and testers take sole responsibility for scenarios
- A desire to have traceability from the acceptance tests back to the acceptance criteria
- Rules expressed as rules in two places – the criteria and the code
- Criteria treated as the specification, rather than using specification by example
If we take the approach of not distinguishing between acceptance criteria and acceptance tests (i.e. see the acceptance tests as the acceptance criteria) then we can encourage teams away from these kinds of problems.
I’m not saying it solves the problem – it’s just easier, in my experience, to move the team towards collaboratively arriving at a shared understanding of the intent of the story this way.
To do this, we need to iteratively evolve our acceptance criteria from rules-oriented to scenario-oriented criteria.
Acceptance Criteria: from rules-oriented to scenario-oriented:
Let’s say we had this user story:
As a snapshot photographer
I want some photo albums to be private
So that I have a backup of my personal photos online
And let’s say the product owner first expresses the Acceptance Criteria as rules:
- Must have a way to set the privacy of photo albums
- Private albums must be visible to me
- Private albums must not be visible to others
We might discuss those to identify scenarios (as vertical slices through the above criteria):
- Create new private album
- Make public album private
- Make private album public
Here, many teams would retain both acceptance criteria and scenarios. That’s ok but I’d only do that if we collectively understood that the information from these two will come together in the acceptance tests… And that whatever we agree in those acceptance tests supersede the previously discussed criteria.
This understanding tends to occur in highly collaborative teams. In newer teams, where disciplines (Business Analysts, Testers, Developers) are working more independently this tends to be harder to achieve.
In those situations (and often even in highly collaborative teams) I’d continue the discussion to iterate over the rules-oriented criteria to arrive at scenario-oriented criteria, carrying over any information captured in the rules, discarding the original rules-based criteria as we go. This might leave me with the following scenarios:
- Create new private album (visible to me, not to others)
- Make public album private (visible to me, not to others)
- Make private album public (visible to me, & others)
Which, with a subtle change to the wording, become the acceptance criteria. I.e. the story is complete when we:
- Can create new private album (visible to me, not to others)
- Can make public album private (visible to me, not to others)
- Can make private album public (visible to me, & others)
Once the story is ‘in-play’ (e.g. during a time-box/iteration/sprint) I’d elaborate these one at a time, implementing just enough to get each one passing as I go. By doing this we might arrive at:
Scenario: Can Create new private album When I create a new private album called "Weekend in Brighton" Then I should be able to see the album And others should not be able to see it Scenario: Can Make public album private Given there is a public album called "Friday Night" When I make that album private Then I should be able to see the album And others should not be able to see it Scenario: Can Make private album public Given there is a private album called "Friday Night" When I make that album public Then I should be able to see the album And others should be able to see it
By being an elaboration of the scenario-oriented acceptance criteria there’s no implied need to also check the implementation against the original ‘rules-oriented’ criteria.
Agreeing that this is how we’ll work, it encourages more collaborative working – at least between the Business Analysts and Testers.
These new scenario-based criteria become the only means of determining whether the intent of the story has been fulfilled, avoiding much of the confusion that can occur when we have rules-oriented acceptance criteria as well as separate acceptance test scenarios.
In short, more often than not, I find these things much easier when the criteria and the scenarios are essentially one and the same.
Why not give it a try?
Old Favourite: Expected Exceptions
Posted by AntonyMarcano in Agile, Software Development, Software Testing on July 24, 2010
This first appeared on my old blog in November 2008.

I’ve decided that I don’t like typical patterns for testing exceptions. I decided this a while ago as far as “Expected Exception” attributes/annotations are concerned and stuck with the traditional try/catch approach (I’ll explain why in a minute). Now, I’ve decided I don’t like the typical “try/fail or catch” approach and have started using a subtle evolution of it.
First, let me explain why I don’t like Expected Exception attributes/annotations. The final nail in the coffin of this approach was hammered home for me when working with Liz Keogh a while back.
Here is an example in Java of your expected exception pattern (for brevity I won’t include assertions for e.getMessage()):
@Test(expected=BeyondMyExpertiseException.class)
public void shouldComplainWhenNotAClass() throws Exception {
DomainExpert expert = new DomainExpert();
String thisCheckpoint = nameOfSomeInterface();
expert.howDoIRestore(thisCheckpoint);
}
So, apart from the obvious fact that it is only implicit as to which method threw that exception (because I know that none of the other steps can throw that exception)… and we want our tests to communicate information explicitly, yes? The insight that Liz shared with me is that it changes the flow of information (ok, I’m paraphrasing now) compared to a test that doesn’t expect an exception.
In a ‘positive’ test, the flow of information that is expressed to the reader is What I need->what I do->what I expect. In an expected exception test, this is changed to what I expect->what I need->what I do. The latter just doesn’t flow very well and because it’s different to your positive tests there’s an overhead involved for the reader (me or someone else later on) to process this shift in structure… I’ve found that such tests just don’t jump out at me when I’m scanning the tests…
Since then, despite fashion, I committed to the old-fashioned way of writing exceptions – “try/fail or catch”:
@Test
public void shouldComplainWhenNotAClass() throws Exception {
DomainExpert expert = new DomainExpert();
String thisCheckpoint = nameOfSomeInterface();
try {
expert.howDoIRestore(thisCheckpoint);
fail("Should have thrown " +
BeyondMyExpertiseException.class.getSimpleName());
} catch (BeyondMyExpertiseException e) {
}
}
Ok, I accept, it looks more cluttered by comparison but the flow of information makes more sense and I make it explicit that the expert.howDoIRestore(thisCheckpoint) method call is the one that should have thrown the exception. (Note: The idea here is not to reduce how much you type but to make the test more expressive). The “try/fail or catch approach only works when your code doesn’t throw an exception… If your code throws a different exception, the failure trace just tells you what exception was actually thrown, it doesn’t tell you what exception was expected. So, here is a slightly different way of writing it:
@Test
public void shouldComplainWhenNotAClass() throws Exception {
DomainExpert expert = new DomainExpert();
String thisCheckpoint = nameOfSomeInterface();
try {
expert.howDoIRestore(thisCheckpoint);
fail();
} catch (Exception e) {
assertThat(e,is(instanceOf(
BeyondMyExpertiseException.class)));
}
}
Notice that I’m only catching Exception now, not BeyondMyExpertiseException. This still feels a little jumbled… Because my assertion is inside the catch block, I have to have the fail() method call just after the call that should throw the exception. Hmmm… don’t like that… Instead, this makes more sense:
@Test
public void shouldComplainWhenNotAClass() throws Exception {
DomainExpert expert = new DomainExpert();
String thisCheckpoint = nameOfSomeInterface();
Exception thrownException = null;
try {
expert.howDoIRestore(thisCheckpoint);
} catch (Exception e) {
thrownException = e;
}
assertThat(thrownException,is(instanceOf(
BeyondMyExpertiseException.class)));
}
Giving this failure trace when it fails:
java.lang.AssertionError:
Expected: is an instance of
com.testingreflections.atdd.expertise.
misunderstanding.BeyondMyExpertiseException
got: < java.lang.UnsupportedOperationException >
So, for those who want to type as little as possible, this isn’t for you… But if you want tests that drive out your exception handling to be more expressive, then this is an alternative to the usual “try/fail or catch” approach. I think that perhaps there’s an even better way of doing this… maybe next I’ll see how approximating closures with an anonymous class might help improve the readability of this… Let me know if you know of a better way.
Antony Marcano is a consultant in software craftsmanship, effective software processes, software quality and software testing. He has over fifteen years experience with... 