Figure 2: We break a story into tasks or steps

Once we have an idea of the tasks or steps involved in achieving the story goal, we talk through concrete examples of these steps. Each example illustrates a different flow through the steps. For our first example, we explore what happens when Stu submits a great essay:

If we map this out into the various tasks we identified earlier, we would get something like this:

Figure 3: Mapping examples

This example might be called a "happy path", but we don't stop here. We look for other examples that illustrate different flows through the story. At each step or task, we can ask questions like: "what else could happen here?" and "what other inputs would change the outcomes?"

For example, what happens if Stu submits a poor essay? We could write another example, like the following:

Stu got 4 in spelling and his essay is returned for correction

If we map this on our feature map, we might get something like this:



Figure 4: Adding a counter-example

Examples and consequences

In the map in Figure 4 I've added a second row in the examples, to represent the case where Stu submits an essay but forgot to use the spell checker. There is something interesting happening in the 'Return to Student' column. I have added a task card (in yellow) called "Tess returns the essay to Stu", but this seems a little inconclusive. The real goal is that Stu receives the essay to correct, not just that Tess has sent it. How do we know that Stu actually received it? To make sure this is the case, and to emphasise the actual outcome we want, I’ve added a Consequence card (in mauve) next to the task where Tess returns the essay to Stu.

Sometimes the map reads more clearly if you have a consequence for each example row. This is especially good for examples that involve calculations.

Sometimes you want to record the consequences for each example more explicitly. Figure 5 shows a Feature Map for a feature about what grade should be awarded for different results. An average of 9 or more is an A, an average of 7-8 is a B, and so forth. In this Feature Map, we add a special Consequence column that contains the consequence of each example row. If you have a lot of consequences that you want to express explicitly, a consequence column can make the map easier to read.

Figure 5: A column of consequences

You don't always need Consequence cards. Many task cards have an implicit consequence that can be shared and understood through conversation between team members. But often they are handy when you want to communicate the expected outcomes more clearly.

This conversation might lead to other examples. Stu got a 4 in spelling, but good marks in other areas, so Tess gave him a chance to correct his work. What would happen if he scored 4 in every category? Would Tess still give him a second chance? What if this was the second time he submitted his essay? And so on. Each of these could become an example. Some, might even be refactored as acceptance criteria for a different story.

You may notice the way I have used lines to connect the tasks, to show the branches and variations in the flow. I find this makes the map clearer and easier to understand. But you could also just repeat the tasks, and have a full row of tasks for each example if you find this expresses your intent better.

Rules explain the examples, examples illustrate the rules

In Example Mapping, we say that examples illustrate business rules, and business rules explain (or give context to) the examples. Both of the previous examples illustrate the same business rule: A teacher can return an essay to a student if any mark is 6 or below. To make this clearer, we can add a card to represent this rule at over the example title cards, as we do with Example Mapping:



Figure 5: Rules explain examples

This lets us explore the scenarios in two dimensions. If we already have an idea of the rules (or some of the rules), we can take a rule and walk through some concrete examples that illustrate this rule. This helps us explore our understanding of the rules by looking for examples and counter-examples. Or we can continue to work through examples ("what else could happen in this task? How would that affect the outcome"), and add rules to explain the new examples as we need them.

We don't need rules for all the scenarios. Many scenarios illustrate the overall flow of a feature, so the rule is simply the goal of the feature. If our application allowed a teacher to return an essay to a student no matter what the mark, the "Can return an essay if any mark is 6 or less" would be unnecessary. In this case, we wouldn't need a rule card for the right-most column. Rather, the overall goal of the feature ("the teacher should be able to return an essay to a student for corrections when the marks are poor") could act as an implicit rule.

Questions highlight uncertainty

The third element of Example Mapping comes into play when you discover something that no one knows. Suppose you know that some subjects marked on a scale of 1 to 10, whereas others from 0 to 10. The BA is aware of this rule, but doesn’t know what subjects it relates to, or whether it is in scope for this story. So she writes it down on a Question card (a pink one, using the Examples Mapping conventions). I like to place these cards under the step they relate to, to give them some context and help identify complexity. A step or task with a lot of questions indicates a lot of uncertainty, and might need refactoring into a story of it’s own.



Figure 6: Questions highlight uncertainty

Working with negative cases

The examples we've seen so far could be described as "happy-day cases", smooth flows through the story. But our acceptance criteria should also describe negative scenarios, especially if they are important to the business. Negative scenarios help understand the positive scenarios better, and help flush out incorrect assumptions or missing details.

Acceptance criteria should record both positive and negative scenarios. However, not all negative scenarios are useful. Field validation rules are fine if the rules relate to business requirements. But a scenario checking for badly-formatted dates or numbers would normally be reserved for unit testing.

For example, the rule that a teacher can return an essay if there is a mark of 6 or under begs the question: can a teacher return an essay if the marks are good? This would justify a separate scenario:

Tess records 9/9/9 for Stu's essay and tries to return it, but she is not allowed to.

The new example could be mapped out like this:

Figure 7: Counter-examples complete the picture

Let’s look at another requirement. Suppose, after some investigation, we learn that the History Department has a police where History exams get a score from 1 to 10. Furthermore, our system needs to cater for history essays.

To illustrate this rule properly, we really need two examples:

one that shows that you can't enter a 0 mark for a History exam,

and another to show that we can enter a 0 mark for some other subject.

We could use examples like these:

Tess records 0/1/2 for Stu's English essay and it is returned for correction

Tess records 0/1/2 for Stu's History essay but she is not allowed save the marks

We could add all of these examples to the feature map as shown here:



Figure 8: Representing negative scenarios

Note how we have described the negative outcome. We just place a corresponding Consequence card underneath the task where it happened.

Adding extra details

Sometimes we want to add some extra information. We might want to add the error message that should be displayed if an invalid mark is entered. Or we might want to add a table of test data describing different variations of the same scenario (for example, different mark weightings for different subjects). I generally put these details on the task card (if there is room), on back of the task card, or sometimes on a card underneath the main task card. The main thing is to have them handy so that we can refer to it later when we automate.

From Feature Mapping to Test Automation

One of the nice things about this approach is that we can start automation immediately. Each example maps to a clear sequence of business-level tasks, which in turn are easy to automate.

Feature Mapping with Cucumber

In Cucumber, for example, we can map the steps more-or-less directly to steps in the Cucumber scenario:

Scenario: Returning an essay to the student for correction A teacher can return an essay to the student to be corrected if any mark is 6 or less Given that Stuart has submitted an essay on 'Politics 101' to be marked And that Tess has opened the essay When Tess records the following marks: | Spelling | Reasoning | Relevance | | 6 | 6 | 6 | And Tess returns the essay to Stuart to be corrected Then Stuart should the 'Politics 101' essay in his Pending Correction list

Feature Mapping with ScreenPlay in JUnit

Using the Screenplay pattern in Java with Serenity BDD, with either JUnit or Cucumber, we could automate these steps like this:

Actor tess = Actor.named("Tess").whoCan(MarkPapers); Actor stuart = Actor.named("Stuart").whoCan(SubmitPapers); givenThat(stuart).wasAbleTo( Submit.anEssayAbout("Politics 101") ); andThat(tess).wasAbleTo( ReviewTheEssay.from(stuart).about("Politics 101") ); when(tess).attemptsTo( RecordMarks(of(6).in(Spelling), of(6)).in(Reasoning), of(6).in(Relevance)), ReturnTheEssay.forCorrections() ); then(stuart).should( seeThat(HisEssays.thatAre(PendingCorrection), contains("Politics 101")) );

Notice how cleanly the tasks map to steps in Cucumber and Java. The structure of the automated tests map closely to the business flow in the examples. This makes both the reporting clearer and the code easier to understand.

At this point, you can automate minimal implementations for your tasks, and you will have a pending executable specification which will act as a starting point for your test automation efforts.

Conclusion

I have found this process very useful for many different types of projects. The clear process it defines makes it easy to pick up for less experienced teams. And mapping out the examples is a great way to flush out the finer points of the requirements. Like Example Mapping, it may be overkill for very simple stories, and will unveil complexity in larger ones. The process should be easy and flow naturally. If it doesn’t, be sure to ask yourself why, and adjust course accordingly.

A special mention goes to Jan Molak, author of Serenity/JS and a major contributor to the Screenplay pattern, for contributing to the Feature Mapping model, reviewing the article and providing valuable suggestions.