Posts Tagged TDD
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 – More Sharks and Delaying Critical Mass
Posted by AntonyMarcano in Agile, Business, Business Analysis, Old Favourites, Project Management, Software Development, Software Testing on June 7, 2011
This article originally featured on my old blog on 19th January 2010.
In a previous post I talked about Critical Mass of software. I showed how an ever-increasing cost of change resulted in it becoming more economical to completely rewrite the system than to enhance and maintain the original.

I explained how this could be avoided by using practices that sustain a consistent and flat cost of change. I also mentioned that you could defer reaching critical mass. Some teams find it difficult to get the time to do this because “the business” always has “more important” or “higher-value” things on their backlog.
What are the implications of reaching critical mass? Well, depending on what the software does and whether the rewritten version still has to do all of those things, it could cost millions… or more.
Presented with the situation that the product could reach critical mass within a year – costing millions to replace – do you think “the business” would start to think it is worth investing in reducing the cost of change? Obviously, I would advise teams to avoid this situation in the first place:

The reality for many teams I’ve encountered is that they don’t feel empowered to push back on the business’ demands for that next feature in half the time it takes to do it properly. If we could present back the impact of that choice as shortening the time to Critical Mass and bringing about costs to replace the software far in excess of the value gained by delivering that feature a month early then perhaps the business would be better informed.

A big visible chart on the wall, showing the estimated point at which Critical Mass was reached could play a big role in getting the business more interested in sustainable change, or at least inspire a conversation on the subject.
Convincing “the business” to invest in some remedial refactoring or allowing three times as long for each feature to facilitate enough remedial refactoring for each new feature and refactoring-as-we-go for the new feature might be easier if we could represent this idea visually:

The problem with this idea is how do we credibly determine when Critical Mass is going to be reached? Many experienced practitioners could probably reasonably accurately estimate when that was going to happen purely on gut feel but this would be torn to pieces by many product managers. I’ve not solved this problem yet because doing this would require a mathematical model, determined by empirical data.
Perhaps someone will take inspiration from the ideas in these blog posts and find a solution. Perhaps someone has already done this or maybe this is an idea for a future PhD I might undertake? Maybe someone else will take inspiration from this article and undertake that work before I do. If so, they’re welcome to (with due attribution where applicable of course
I think it is possible, however, to come up with a simple model based on the average complexity per unit of value (assuming that the team is using value and complexity). Trending this and keeping an estimate of a complete re-write up to date might allow the simple charts above to be maintained along side release-level burn-down charts.
These ideas are still in their infancy for me. Has this problem been solved already? If not, I encourage others to explore my hypothesis and help take it from just an interesting idea to something more useful.
Old Favourite – Sharks, Debts, Critical Mass and other reasons to Sustain Quality
Posted by AntonyMarcano in Agile, BDD/ATDD, Business, Business Analysis, Old Favourites, Project Management, Software Development, Software Testing on June 7, 2011
This article originally featured on my old blog on 18th January 2010.
A while back I tweeted about critical mass of software:
Critical Mass of Code – past which the changeability of the code is infeasible, requiring that it be completely rewritten.
An elaboration of this might be:
Critical Mass of Software: the state of a software system when the cost of changing it (enhancement or correcting defects) is less economical than re-writing it.
This graph illustrates a hypothetical project where the cost of change increases over time (the shape of which reminds me of a thresher shark):

Note:The cost of a rewrite gradually grows at first to account for the delay between starting the re-write and achieving the same amount of functionality in the original version of the software at the same point in time. The gap between the cost-of-change and the cost-of-rewrite begins to decrease as the time it takes to implement each feature of comparable benefit in the original version grows.
It was just one of those thoughts that popped into my head. I soon discovered that critical mass of software is not a new idea.
One opportunity that I feel organisations miss out on is that this can be used as a financial justification for repaying technical debt, thus preventing or delaying the point at which software reaches its Critical Mass, or avoiding it altogether.
Maintaining quality combined with practices that keep the effort involved in completing each feature from growing over time can defer critical mass indefinitely:

Note: The cost of a rewrite is slightly less at first assuming that we are doing a little extra work to ensure that we get the infrastructure we need up and running to support sustainable change (e.g. continuous integration etc.)
This flat cost of change curve is one of the motivations of many agile practices and software craftsmanship techniques, such as continuous integration, test-driven-development, behaviour driven development and the continuous refactoring inherent in the latter two. A flat cost-of-change trend is good for the business, as they have more predictable expenditure.
The behaviour I’ve noticed with some teams is to knowingly accrue technical debt to shorten time to a near-future delivery in order to capitalise on an opportunity and then pay it back soon after:

This certainly defers reaching critical mass but it doesn’t prevent it.
Unfortunately, I see more teams taking on technical debt and not repaying it (for various reasons, often blamed on “the business” putting pressure on delivery dates).
If we had a way of estimating the point at which we’d reach critical mass, we’d be able to compare the benefit of repaying technical debt now in order to avoid or delay the cost of a rewrite… or even better, demonstrate the value of achieving a flatter cost of change.
I’m not sure that we have the data or the means of predicting it, but perhaps these illustrations of a hypothetical scenario will help you explain why sustaining constant quality, automating repeatable tests (or checking as some prefer to call it) wherever technically possible and, on those occasions when we do need to make a conscious choice to compromise quality to capitalise on an opportunity, that the debt is repaid soon after.
One company I know reached this point a couple of years ago and embarked on a department wide transformation to grow their skills in agile methods so that they not only re-wrote the software but could also avoid ever reaching critical mass again. A bold move, but one that paid off within a year. Even for them, they’ll need to avoid complacency as time goes on and not forget the lessons of the past. Let’s hope they do.
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.
Being a youDevise Developer – Week 1
Posted by AntonyMarcano in Uncategorized on July 18, 2010
In my previous post, I gave the background to me spending the next month or two as a developer on a youDevise product.
I’ve just completed my first ‘official’ week working with them. It was one of, if not, the smoothest of inductions I’ve ever experienced. I arrived and was shown a desk to work at. There was a welcome letter in front of a dual screen developer machine with Ubuntu installed. The letter told me everything I needed to get logged in, access e-mail and wiki links telling me where to find the rest of the information I needed to configure the machine. For the project I was about to work on.
Their CEO sent out an introduction e-mail telling everyone about me and others who started that day on the development team and in other non-technical departments. I also experienced a warm welcome from the team and was assigned a youDevise mentor to help me settle in.
My first few days involved several presentations – mostly demonstrative – introducing me to youDevise products and their business model. Yet I still got to work on code almost immediately.
I was very lucky to get to pair with their summer intern, Marius Cobzarenco, on a part of an all-new reporting capability for one of their products. I am so impressed with Marius. He left Cambridge University only three weeks ago and I have to say he is one of the most competent graduates that I’ve ever met! He has a level of technical competence that rivals many much more experienced developers and he has a passion and aptitude for learning that is rare. He became competent in Behaviour Driven Development after working with me for only an hour or two and fell in love with the approach. I was so impressed with him that I decided to sponsor his attendance at a TDD workshop this weekend with Jason Gorman.
Marius is a reflection of the high standards youDevise sets for itself. Whenever I’m there, I never feel like the smartest person in the room.
Speaking of smart people, other youDevisers I’ve also had the opportunity to work with include Joe Schmetzer and Stephen Siard.
Joe is a great guy – extraordinarily capable yet incredibly humble. Joe really knows his stuff! I’m looking forward to sharing with him, but mostly, learning from him. Stephen – who I have secretly, in my mind, nicknamed ‘the professor’ simply because his intellect is especially humbling for me – is another who I have been very lucky to work with. He has a way with algorithms that is tantamount to wizardry – but he is far too scientific to be called “the wizard”
These guys stand alongside other similarly impressive and diverse individuals that I’ll mention in future posts – each with their unique talents.
Next week, we start a new iteration. I’ll be seeing what it’s like working with some of their legacy code. Based on what I’ve seen so far, at least I know they recognise where they have legacy and that they are passionate about writing tests and cleaning the code up as they go.


Antony Marcano is a consultant in software craftsmanship, effective software processes, software quality and software testing. He has over fifteen years experience with... 