Defining and illustrating features - What do I want? Defining requirements using BDD - BDD in Action: Behavior-Driven Development for the whole software lifecycle (2015)

BDD in Action: Behavior-Driven Development for the whole software lifecycle (2015)

Part 2. What do I want? Defining requirements using BDD

Chapter 4. Defining and illustrating features

This chapter covers

· Describing and organizing features and user stories

· Illustrating features with examples

· Using these examples to build up a common understanding of the requirements

In the previous chapter you learned how important it is to understand why you’re building a piece of software and what its ultimate purpose will be in business terms. We looked at how you can clarify what you want to achieve and how you expect this to benefit the business (the business goals), and also at who will benefit or be affected by the project (the stakeholders) and what you need to deliver at a high level to achieve the business goals (the capabilities).

Now it’s time to describe how you can provide these capabilities. In this chapter we’ll learn about what BDD practitioners often refer to as features, and about some of the techniques they use to describe and discuss these features (see figure 4.1):

Figure 4.1. In this chapter we’ll focus on how to discover and describe the features that will enable your application to achieve its business goals.

· In BDD terms, a feature is a piece of software functionality that helps users or other stakeholders achieve some business goal. A feature is not a user story, but it can be described by one or several user stories.

· A user story is a way of breaking the feature down into more manageable chunks to make them easier to implement and deliver.

· BDD practitioners use concrete examples to build up a shared understanding of how a feature should behave. These examples also help flush out and clarify ambiguities and uncertainties in the requirements.

· Managing uncertainty plays a major role in BDD practices. When they’ve identified areas of uncertainty, experienced BDD practitioners avoid committing to a definitive solution too early, keeping their options open until they know enough to be able to deliver the most appropriate solution for the problem at hand. This approach is known as Real Options.

· Deliberate Discovery tries to reduce project risk by managing uncertainty and ignorance proactively wherever possible.

· The examples that illustrate the features help drive the development process, becoming automated acceptance criteria that the developers use as a guide when they implement the features.

Let’s look at these points in more detail.

4.1. What is a “feature”?

In Agile projects, developers use lots of different words to describe what they want to build (see figure 4.2). Epics, capabilities, themes, requirements, features, use cases, user stories, tasks. Confusing? Guilty as charged. The Agile community has done a relatively poor job of defining these concepts in a clear and universally understood way. Different methodologies and different teams use varying—sometimes contradictory—terms. And although the terms “user story,” “epic,” and “theme,” for example, do actually have a long tradition in Agile and Scrum circles, many teams still waste long hours debating what terminology they should use, or whether a particular requirement should be called a story, a feature, an epic, or something else entirely.

Figure 4.2. The vocabulary around Agile requirements can be a little confusing at times.

How did we get ourselves into this predicament? All we really want to do is describe what we think our users need. We want to express ourselves in a way that business stakeholders can understand, so that they can validate our understanding, contribute, and provide feedback as early as possible. We want to be able to describe what our users need in a way that makes it easier to build and deliver software that meets these needs.

The terms we use are intended to simplify discussion around user requirements. In essence, we’re trying to do two things:

· Deliver tangible, visible value to the business at regular intervals

· Get regular feedback so we know if we’re going in the right direction

The way we describe and organize the requirements should support these goals. The various ways different teams organize and structure stories, epics, features, and so forth are simply ways to decompose higher-level requirements into manageable sizes, describe them in terms that users can understand, and allow them to provide feedback at each level. There are many perfectly legitimate ways to do this, and what works best for your team will depend on the size and complexity of your project and on the background and culture of your organization and team members.

For the sake of simplicity and consistency, let’s step through the vocabulary we’ll use throughout the rest of this book. We’ll mainly be dealing with four terms: capabilities, features, user stories, and examples (see figure 4.3).

Figure 4.3. Features deliver capabilities to stakeholders. We’ll use user stories to plan how we’ll deliver a feature. We’ll use examples to illustrate features and user stories.

I introduced these concepts in the previous chapter, but here’s a quick refresher:

· Capabilities give users or stakeholders the ability to realize some business goal or perform some useful task. A capability represents the ability to do something; it doesn’t depend on a particular implementation. For example, “the ability to book a flight” is a capability.

· Features represent software functionality that you build to support these capabilities. “Book a flight online” would be a feature.

· When you build and deliver these features, you can use user stories to break down the work into more manageable chunks and to plan and organize your work.

· You can use examples to understand how the features will help your users and to guide your work on the user stories. You can use examples to understand both features and individual user stories.

4.1.1. Features deliver capabilities

As developers, we build features so that end users, and stakeholders in general, can achieve their goals. Users need our software to give them the capabilities that will help them contribute to these business goals.

Features are what we deliver to users to support these capabilities. A feature is a tangible piece of functionality that will be valuable for users, that relates closely to what the users actually ask for, and that may or may not be deliverable in a single iteration. It can be delivered relatively independently of other features and be tested by end users in isolation. Features are often used to plan and document releases.

Features are expressed in business terms and in a language that management can understand. If you were writing a user manual, a feature would probably have its own section or subsection. Back in the day when off-the-shelf software was packaged in boxes, features would be what appeared on the side of the package.

Let’s look at an example. Flying High Airlines is very proud of its recently introduced Frequent Flyer program. Belonging to the Flying High Frequent Flyer club lets members earn points that they can spend on flights or upgrades and so forth, and it’s designed to encourage travellers to book with Flying High rather than a competitor. But management has noticed a high rate of lapsed memberships, which they suspect is due to the cumbersome renewal process. Currently, members need to call Flying High or return a renewal form by non-electronic mail to renew.

Suppose you have identified the capability, “to enable members to renew their membership more easily.” Some useful features supporting this capability on the Flying High customer site might be “allow members to renew their membership online” and “notify members when their membership is due for renewal.” To support these capabilities, you could define features such as “renew membership online” or “notify members that their membership is due for renewal by email” (see figure 4.4).

Figure 4.4. Features provide users or stakeholders with the capability to do something useful.

Let’s focus on the online renewal feature. You could describe the “online membership renewal” feature using the “in order to ... as a ... I want” format, like this:

You used this format in the previous chapter to describe capabilities, but it works equally well for requirements at any level. You start off with a short summary or title of the feature to give some context . This is the text proposed in the impact map in figure 4.4, in the “How” section. In fact, until you come to actually scheduling, designing, and implementing this feature, this short overview is usually enough to work with. You only really need to flesh out the details when you’re fairly sure you want to (and are ready to) start working on the feature.

At that point, you can try to formulate what the feature is about in more detail. First you outline what business goal you think this feature will support . This helps remind you why you’re building this feature in the first place, and ties back nicely to the capability in the impact graph. It also allows you to do a sanity check on your requirement. You can ask yourself questions like, “Will the feature I’m proposing really help us achieve this business goal? If not, what business goal is it supporting? Based on what I know now, is it still worth building this feature?” Both your understanding of the requirements and the business context behind the project may have changed since you first envisaged the feature (see figure 4.5), and you might need to reevaluate how important the feature really is.

Figure 4.5. Sometimes features become less important as we learn more about them.

Next, you identify which users you think this feature will affect, or which stakeholders will benefit . This helps you look at things from the point of view of the people who will be using the feature or who expect to benefit from its outcomes.

Finally, you describe the feature itself and what it’s meant to do . Here you focus on describing what the software does in business terms; you don’t want to get too hung up on the technical details or commit yourself to a particular implementation just yet.

Sometimes it’s more useful to consider a requirement not from the point of view of the end user, but from the perspective of the stakeholder who’s ultimately interested in this business outcome. For example, you might find it more useful to look at things from the point of view of the business:

This highlights an interesting point. It’s really the Flying High sales manager who wants members to renew so they’ll continue to book flights on Flying High planes . So in this case, the real stakeholder that you need to satisfy is the sales manager, not the members. Maybe the members aren’t always that motivated to renew. Maybe you need to find ways to entice them into renewing their memberships.

The format we’ve been using here is popular among BDD practitioners because it focuses on the business value or capability that the feature is meant to deliver. But many teams also use the more traditional “as a ... I want ... so that” format:

If you’re new to all this, the “in order to ... as a ... I want” format will help you stay focused on the business goals, but both forms are valid, and they convey essentially the same information. Experienced practitioners will be able to produce high-quality and meaningful definitions in both formats.

Ultimately, there’s no right or wrong way to describe a feature, and no standard canonical format that you must use, though it’s nice to agree on a consistent format within a team or project.

Exercise 4.1

Look at the impact map in figure 4.6. You want to give call center staff the capability to sell tickets more quickly over the phone. Define some features that would help support this capability.

Figure 4.6. What features would support this capability?

4.1.2. Features can be broken down into more manageable chunks

When you describe a feature, you need to think in terms of functionality that delivers some useful capability to the end user. When you come to building and delivering a feature, you’ll often need to break the feature down into smaller, more manageable pieces. You may or may not be able to deliver the whole feature in one iteration.

You can break features down further as you explore the best way to deliver a particular capability, using what’s effectively a form of functional decomposition. In an Agile project, when you’ve broken the features down into chunks small enough to build within a single iteration, you can call the chunks “user stories.” As you can see in figure 4.7, it’s common to need more than one level of decomposition to get from a real-world feature to a reasonable-sized user story.

Figure 4.7. Breaking down features into smaller features or user stories makes them easier to organize and deliver.

Knowing when the decomposed chunks are no longer features is a little subjective and varies from project to project. As we discussed earlier, a feature is something that users can test and use in isolation. A feature can deliver business value in itself; once a feature is completed, you could theoretically deploy it into production immediately, without having to wait for any other features to be finished first. Let’s look at some examples:

· “Online membership renewal” would certainly qualify as a feature. If you were to deploy this feature into production by itself, it would still be of significant business value. But could you provide business value faster by incrementally delivering smaller parts of this feature, rather than waiting for it to be completely finished? This is generally a question for the business stakeholders.

· “Renew membership by credit card” would not be a feature in itself unless it included the entire renewal process. Even if it did, you’d still have to ask the project sponsor if they would be happy to deploy this feature into production without the other payment methods.

· “Pay renewal fees with Visa” and so forth would usually be considered too low-level to be delivered in isolation. Paying by Visa, for example, is just one aspect of “Renew membership by credit card,” and would be of little business value in isolation. So you’d represent these in the form of user stories rather than features.

There are two main strategies when it comes to decomposing features. The one used here involves decomposing a feature into a number of smaller business processes or tasks (“Renew by credit card,” “Pay with MasterCard,” and so forth). You express tasks in terms of business goals and try to avoid committing to a particular implementation solution until you know more about what solution would be most appropriate. When you use this strategy, visual approaches such as Impact Mapping also make it easier to keep the larger business goals in perspective. This is generally the approach that works best when practicing BDD (and Agile in general, for that matter).

The other strategy that teams sometimes use is deciding what needs to be built early on, and coming up with user stories to deliver whatever technical solution is envisaged. This approach is risky and involves much more upfront work, with the dangers that that entails. For example, figure 4.8 shows a different decomposition of the “Membership renewal online” feature into a number of user stories.

Figure 4.8. It’s dangerous to decompose features with a particular solution in mind.

In this decomposition, you’ve already imagined or designed a particular sequence of screens to implement this feature and have created user stories based on these screens. The problem is that you can lose focus on the real business goals when you commit early to a given solution, and you can miss the opportunity to provide a more appropriate solution. In figure 4.8, for example, the ability to renew memberships using Frequent Flyer points has been forgotten in all the excitement around implementing a PayPal-based solution.

4.1.3. A feature can be described by one or more user stories

User stories are the bread and butter of Agile projects, and they’ve been around, in slightly differing forms, since the origins of Agile. A user story is a short description of something a user or stakeholder would like to achieve, expressed in language that the business can understand. For example, the following user story describes a requirement around forcing users to enter at least a moderately complex password when they register to be a Frequent Flyer member. For this story, you can use a format very similar to the ones used for features earlier on:

Agile practitioners are fond of emphasizing that a user story is not actually a requirement, but more a promise to have a conversation with the stakeholders about a requirement. Stories are a little like entries in a to-do list, giving you a general picture of what needs to be done, and reminding you to go ask about the details when you come to implement the story.

User stories are traditionally represented on story cards like the one in figure 4.9, which also includes other details, such as a priority and a rough estimate of size in some agreed metric (estimates are often in hours, or they may use the more abstract notion of “story points”). You can also use similar cards to represent features.

Figure 4.9. A typical user story card format

#120 Providing a secure password when registering

In order to avoid hackers compromising member

accounts

As the systems administrator

I want new members to provide a secure password

when they register

Priority: HIGH

ESTIMATE: 4

On the flip side of the card, you can put an initial list of acceptance criteria in simple bullet points (see figure 4.10). These acceptance criteria clarify the scope and boundaries of the story or feature. They help remove ambiguities, clarify assumptions, and build up the team’s common understanding of the story or feature. They also act as a starting point for the tests. But the aim of these acceptance criteria isn’t to be definitive or exhaustive. It’s unreasonable to expect the product owner or stakeholders to think of a definitive list of the acceptance criteria when the stories are being discovered. You just want enough information to be able to move forward. You’ll have plenty of time to refine, expand, and complete them, and to add any additional requirements documentation that the team might need, when it comes to implementing the story, and even later on when you learn more about the requirements.

Figure 9.10. You can put an initial list of acceptance criteria on the back of the story card.

- password should be at least 8 characters

- password should contain at least 1 digit

- password should contain at least 1 PUNCTUATION

MARK

- I should get an error message telling me what I

did wrong if I enter an insecure password

As you can see in figure 4.10, these user stories look a lot like features, but they tend to be a little lower-level. A user story doesn’t have to be deliverable in isolation but can focus on one particular aspect of a feature. User stories can help you plan and organize how you’ll build a feature. Although you may not deliver a user story into production by itself, you can and should show implemented stories to end users and other stakeholders, to make sure that you’re on the right track and to learn more about the best way to implement the subsequent stories.

You can use user stories to break down the features we discussed in the previous section. For example, figure 4.11 builds on figure 4.4, continuing the investigation of what features might help you reduce lost revenue from lapsed Frequent Flyer memberships.

Figure 4.11. You can break large features down into smaller, more manageable ones.

One of the features you discovered for this requirement was “Email notification of lapsing membership.” This is a fairly large piece of work, so you could break it down into stories like the following:

· Send notification emails to members whose membership will finish within a month.

· Configure notification message texts.

· Open renewal page from the notification email.

Although each of these stories adds business value in its own way, these stories aren’t designed to be deployed into production independently. But they do provide great opportunities for getting useful feedback from stakeholders.

For example, suppose you’re working on the following story:

Story: Send notification emails to members whose membership will finish

within a month

In order to increase retention rates for our Frequent Flyer program

As a sales manager

I want members to be notified a month before their memberships finish

When you show the implementation of this story to the Flying High sales manager, the conversation goes something like this:

You: And this is how the email notification works. When their membership is about to expire, they receive an email that looks like this.

John the Sales Manager: Looks good. And what about the follow-up email?

You: Is there a follow-up email?

John: Of course. Bill from marketing wants a follow-up email that will include a discount offer of some kind to encourage ex-members to come back.

You: And is the discount always the same?

John: No, Bill needs to be able to change it depending on his latest marketing strategy. We talked about configuring the messages last time.

The value of this sort of feedback is huge. You’ve just discovered a new story for a requirement that had been overlooked or initially misunderstood: “Send follow-up notification emails to ex-members whose membership has just lapsed.”

In addition, you now have a clearer understanding of what’s expected regarding the “Configure notification message texts” story, which we’ll look at next. Originally this was conceived of as a configurable template that the development team could change when required and deliver in the next release. But based on this conversation, you now know that the marketing people want to be able to configure the message at any time. So you can now describe this next story as follows:

Story: Include a configurable incentive in the follow-up notifications

In order to increase retention rates for our Frequent Flyer program

As a sales manager

I want to be able to include a configurable text describing incentives to

rejoin such as discount offers or bonus points in the notification message

This example illustrates another point. User stories allow you to put off defining detailed requirements until as late as possible. As time goes on, you’ll learn more and more about the system you’re delivering. This is what the ongoing conversations promoted by BDD are designed to facilitate. If you specify the details of a user story too early, you may miss some important fact that you’ll learn later on. If you went ahead and specified the details of the “Configure notification message texts” story first, you’d implement a piece of functionality with little business value, and it wouldn’t correspond to the stakeholders’ expectations at all.

But you can’t procrastinate forever. If you leave it too late, you won’t have time to talk to stakeholders and understand the detailed requirements before the feature is due. In lean software development, this is known as the last responsible moment. This concept is also heavily used in an approach called Real Options, which we’ll look at in more detail in section 4.3.

Exercise 4.2

Develop the features you defined in the previous exercise, and break them down into stories of different sizes until you get to stories that you think are of a manageable size. Describe some of them in more detail using the “in order to ... as a ... I want” format.

4.1.4. A feature is not a user story

In many projects, the features we’ve been discussing would be represented as high-level user stories, and some teams don’t find it necessary to break the features down into smaller stories. This is fine and will work well on smaller projects.

But there are some advantages to keeping a distinction between the two. Remember,

· A feature is a piece of functionality that you deliver to the end users or to other stakeholders to support a capability that they need in order to achieve their business goals.

· A user story is a planning tool that helps you flesh out the details of what you need to deliver for a particular feature.

You can define features quite a bit ahead of time, but you only want to start creating stories for a feature when you get closer to actually implementing the feature.

It’s important to remember that user stories are essentially planning artifacts. They’re a great way to organize the work you need to do to deliver a feature, but the end user doesn’t really care how you organize things to get the feature out the door, as long as it gets delivered. Future developers are more interested in what the application currently does than how you went about building it.

Once the feature has been implemented, the user stories can be discarded. The description of the features (see section 4.1.1) is generally more effective at describing what the application does. The examples you use to illustrate the features and stories (see section 4.2) do a great job of illustrating how the software actually works, as do the automated acceptance criteria that you’ll write later on in this book.

4.1.5. Epics are really big user stories

Many teams, especially ones that use Scrum, use the term “epic” to refer to a very large user story that will eventually be broken down into smaller stories. There’s no magic definition for what makes a story epic, but if a story turns out to be so big that it needs several sprints to complete, it would typically be broken up into a number of smaller, more manageable user stories.

There are a few obvious similarities between the definition of features in section 4.1.1 and the way I’m describing epics. Both may need to be broken down into a number of smaller stories, and both can span several iterations. Epics, like features and stories, are focused on delivering business value to the users in some form. But epics, like stories, are primarily useful for project planning.

We won’t use epics much in the rest of this book, but let’s see how an epic would fit in with the requirements organization we’ve been looking at so far. If your idea of an epic is simply a very large user story that can be broken down into smaller user stories, then epics would fit under features, or possibly be synonymous with features (see figure 4.12).

Figure 4.12. Some teams simply define epics as very large user stories.

Some teams see epics as much more, well, epic, and would place them above features. In that case, they’re probably using a different, more granular, definition of the word “feature.”

In any case, as you saw earlier, it’s perfectly reasonable to have several levels of decomposition before you get to the user stories that you can implement in a sprint.

4.1.6. Not everything fits into a hierarchy

In real-world projects, not all requirements fit into the sort of neat hierarchical structures we’ve been talking about. Although this will work for many user stories, you’ll sometimes come across a story that supports several features. For example, the “providing a secure password when registering” story we discussed in section 4.1.3 might relate to two features:

· Join the Frequent Flyer program online.

· Keep client data safe.

In that situation, you might say that the “join the Frequent Flyer program online” feature is a logical parent for this user story, but it’s clearly also related to the cross-functional feature, “keep client data safe.” This often happens when multiple stakeholders are involved. In this case, the business stakeholder wants travellers to be able to join the Frequent Flyer program, and the security stakeholder wants the feature to be delivered safely. There may be other stakeholders as well, such as compliance, legal, operations, and so forth.

Tags are a good way to handle this sort of situation. Many requirements-management and reporting tools let you use tags to organize your requirements, in addition to enabling a more conventional parent-child relationship. This way, you can present a relatively structured view of the main requirements hierarchy, but also keep track of any looser relationships. We’ll look at using tags as part of the living documentation in part 3 of this book.

Once you have a better idea of which features you want to build, you need to flesh out your understanding of them. One of the best ways to do this is to talk through some concrete examples.

4.2. Illustrating features with examples

Examples are at the heart of BDD. In conversations with users and stakeholders, BDD practitioners use concrete examples to develop their understanding of features and user stories of all sizes, but also to flush out and clarify areas of uncertainty (see figure 4.13). These examples, expressed in language that business can understand, illustrate how the software should behave in very precise and unambiguous terms.

Figure 4.13. The essence of BDD, according to its inventor Dan North

According to David Kolb’s Experimental Learning theories, effective learning is a four-stage process.[1] In Kolb’s model, we all start learning from concrete experiences of some real-world situations or events (experience). When we observe and think about an experience (reflection), we analyze and generalize that example, forming a mental model that represents our current understanding of the problem space (conceptualize). Finally we can test this mental model against other real-world experiences to verify or invalidate all or part of our understanding (test).

1 David A. Kolb, Experiential Learning: Experience as a Source of Learning and Development (Prentice Hall, 1984).

BDD uses a very similar approach (see figure 4.14), where examples and conversation with users, stakeholders, and domain experts drive the learning process. You discuss concrete examples of how an application should behave and reflect on these examples to build up a shared understanding of the requirements . Then you look for additional examples to confirm or extend your understanding .

Figure 4.14. David Kolb’s Experimental Learning theories apply well to BDD.

Let’s see how this works in practice. The story card and the initial acceptance criteria jotted down on the back (figures 4.9 and 4.10) make a great place to start a conversation that will discover these examples. To see what such a conversation might look like, let’s revisit the “secure password” user story we discussed in section 4.1.3.

The “secure password” story you defined earlier went like this:

Story: Providing a secure password when registering

In order to avoid hackers compromising member accounts

As the systems administrator

I want new members to provide a secure password when they register

You also had an initial set of acceptance criteria:

· The password should be at least 8 characters.

· The password should contain at least 1 digit.

· The password should contain at least 1 punctuation mark.

· I should get an error message telling me what I did wrong if I enter an insecure password.

These acceptance criteria are a good start, but there are still some potential ambiguities. Can you have all lowercase characters, or do you need a mixture of uppercase and lowercase? Does the position of the number in the password matter? How detailed should the error message be?

When you talk to the systems administrator about this story, you could use examples to try to clarify these questions and others (because you certainly haven’t thought of everything). You can use a few key examples as the basis for your formal acceptance criteria (we’ll discuss how to express acceptance criteria in a more structured way in the next chapter). Not all of the examples that you’ll discover in these conversations will make it into the scenarios—many will just be useful to guide the conversation and expand your understanding of the problem space.

This sort of conversation is more productive if you use some simple strategies. Remember, the aim of this exercise is to build a mental model of the requirements and to illustrate this mental model with a number of key examples. Think of the problem space for the story as a set of jigsaw puzzle pieces. When you ask for an example, you’re really asking for clarification of your understanding of the requirements. This is like picking up a piece of the jigsaw and placing it where you think it should go. If it fits, you’ve confirmed your understanding and expanded your mental model. If it doesn’t, then you’ve flushed out an incorrect assumption and can move forward on a more solid basis.

Back to our password scenario. Raj the System Administrator is an expert in system security and knows a great deal about what makes a secure password. Raj is very concerned about this problem, as in his experience most users naturally use passwords that are very easy to hack. To clarify the exact requirements, you take Susan, a tester, and Joe, a developer, along to see Raj to learn more about what he needs. The conversation with Raj goes along the following lines:

You: I’d like to make sure I’ve understood what you need for the “secure password” story. The first acceptance criteria we defined is about password length. So a password should be rejected if it has less than 8 characters?

Raj: Yes, that’s right. Passwords need to be at least 8 characters to make it harder for hacking algorithms to guess them.

You: So “secret” would be rejected because it has only 6 characters?

Raj: Correct.

You: So what about “password”. Would that be acceptable?

Raj: No, we also said that we need at least 1 digit.

You: So we did. So “password1” would be OK?

Raj: No, actually that’s still really easy to hack. It’s a word from a dictionary: the digit at the end wouldn’t slow down a hacking algorithm for very long. Random letters and punctuation marks make it a bit harder.

You: OK, so would “password1!” be OK? It has a number and an exclamation mark, and it has more than 8 characters.

Raj: No, like I said, using words from a dictionary like “password” is really bad. Even with numbers and punctuation, a hacking algorithm would solve that pretty much instantaneously.

Notice what has just happened here. You are testing your assumption that the initial acceptance criteria represent all of the constraints that make a secure password. At each step, you used a different example to verify your understanding of the various rules. Now you seem to have found another requirement that you need to represent: dictionary words should be avoided. You decide to push this further:

You: How about “SeagullHedgehog”?

Raj: That would be better.

You: But there are no numbers or punctuation marks in it.

Raj: Sure, that would make it better. But it’s still a random sequence of words, which would be pretty hard to crack.

You: How about “SeagullHedgehogCatapult”?

Raj: Pretty much uncrackable.

To keep track of these cases, Susan the tester has been noting a simple table of examples to use for her tests. Here’s what she has so far:

Password

Secure

secret

No

password

No

password1

No

SeagullHedgehog

Yes

SeagullHedgehogCatapult

Yes

You decide to check another of your assumptions:

You: OK, how about “aBcdEfg1”?

Raj: That one would actually be pretty easy for a machine to crack—it’s just a sequence of alphabetically ordered letters and a number. Sequences are easy to crack, and just adding a single number at the end doesn’t add much complexity.

You: What about qwertY12

Raj: That’s just a sequence of keys on the keyboard. Most hacking algorithms know about that trick, so it would be very easy to guess.

You: Oh. OK, how about “dJeZDip1”?

Raj: That would be a bit short, but OK.

So now you have another requirement: alphabetical sequences of letters or spatial sequences of keys on the keyboard are both a no-no. But you’ve noticed something interesting:

You: Raj, rather than just saying if a password I give you is secure or not, you seem to be grading them by how hard they are to hack—is that intentional?

Raj: Well, I wasn’t thinking of it like that, but yes, of course: the whole point of a secure password is so that it doesn’t get hacked, and the passwords most people use are pretty easy to hack.[2] There are a lot of studies and a lot of algorithms out there that measure password strength.[3]And many sites provide feedback on the strength of the passwords you enter. In those terms, we need passwords to be of at least medium strength.

2 See, for example, Dan Goodin, “Anatomy of a hack: even your ‘complicated’ password is easy to crack,” http://www.wired.co.uk/news/archive/2013-05/28/password-cracking.

3 For anyone interested in this field, there’s an interesting article on password strength by Dan Wheeler, “zxcvbn: realistic password strength estimation,” at https://tech.dropbox.com/2012/04/zxcvbn-realistic-password-strength-estimation.

Raj brings up a screen similar to the one in figure 4.15.

Figure 4.15. A password security meter helps users provide more secure passwords by measuring how easy a password would be to crack.

You: Raj, I think we’ve been focusing on the detailed rules for password validation too much. Working through these examples seems to indicate that the rules are less clear-cut than we initially thought. And the rules we’re describing focus on one particular solution to the problem we’re trying to solve: the real value in this story comes from ensuring that users have a strong password, not enforcing a particular set of rules. If we reason in terms of password strength rather than specific rules, maybe we could rephrase the acceptance criteria like this:

· The password should be at least of medium strength to be accepted.

· I should be informed of the strength of my proposed password.

· If the password is too weak, I should be informed why.

Raj: Yes, that sounds fine. But how do we know what qualifies as a medium-strength password? (See figure 4.16.)

Figure 4.16. Password strength is not as simple as it seems (courtesy of xkcd.com).

Joe: It looks to me like we have a few options there. We can either write our own password-strength algorithm or use an existing one. There are pros and cons to each approach, but using an existing library would probably be faster to implement.

You: Let’s keep our options open: we don’t know enough about what will suit us best to commit to a particular solution just yet, so let’s do what we can to learn more. We’ll see if we can find a good existing library and experiment with it, but we should integrate it in a way that we can easily switch to another library or our own custom solution later on if we aren’t happy with the one we find.

Joe: Raj, I should be able to build a version of this using a couple of possible libraries by Thursday that you can play around with. Based on your feedback, we can fine-tune the solution we pick, or try out another one.

Susan: We can use this table of sample passwords as a starting point for the acceptance criteria. We may refine it or add new examples later on as we learn more about what we can do.

Password

Strength

Acceptable

secret

Weak

No

password

Weak

No

password1

Weak

No

aBcdEfg1

Weak

No

qwertY12

Weak

No

dJeZDip1

Medium

Yes

SeagullHedgehog

Strong

Yes

SeagullHedgehogCatapult

Very Strong

Yes

You’ve now gone from having what appeared to be a clear and simple set of requirements to discovering that the real requirements are not quite so obvious. What initially appeared to be business rules requested by the user turned out to be just one possible solution to the underlying business problem of ensuring that members have secure passwords. The team identified several possible approaches, but deferred choosing a specific option until they knew more about what solution they would use. And they identified a strategy that the team could use to get useful feedback from the business; this will help them select the most appropriate solution.

This sort of situation occurs often in software development; it’s important to know what you don’t know, and to cater for it in your decisions. In fact, many of the design decisions the team made in this example are founded on two important BDD concepts: Real Options and Deliberate Discovery.

4.3. Real Options: don’t make commitments before you have to

In the mid-2000s, Chris Matts identified a fundamental principle underlying many Agile practices: putting off decisions until the “last responsible moment,” an idea that comes from lean software development. He called this principle Real Options. Understanding this principle changes the way you think about many Agile practices and opens the door to a few new ones.

In finance, an option gives you the possibility, but not the obligation, to purchase a product sometime in the future at today’s price. For example, imagine that there’s a high probability that you’ll need to purchase a large quantity of steel in the next three months, and that the price of steel is currently on the rise. You don’t want to buy the steel now, because you aren’t completely sure that you’ll need it; you expect to know for sure sometime in the next two months. But if you wait another few months, the price of steel might have gone up, which means that you’ll lose money. To get out of this conundrum, you can buy an option to purchase the steel sometime within the next three months, at today’s price. If the price of steel goes up, you can still buy at today’s price. And if the price goes down, or if you don’t need the steel, you can choose not to use the option. You need to pay for this option, but it only costs a fraction of the total price of the steel: it’s worthwhile because it allows you to not commit yourself to buying the steel until you’re sure you need it.

This principle also applies in day-to-day life. When you buy a plane ticket, you’re actually buying an option to travel: the ticket places you under no obligation to travel. But the price you pay for this option varies. Imagine your favorite airline is offering tickets for only $600 to go from Sydney to Wellington, but these cheaper tickets are nonrefundable if you decide not to travel. You’re not sure that you’ll be able to make the trip, so you opt for a more expensive $800 ticket, which has a $25 cancellation fee.

Let’s look at the math here. The option to cancel the flight costs you an extra $200. If you’re fairly likely to travel, this might be a lot to pay for an option you’re unlikely to use, so you might prefer the cheaper ticket. But if you think that there’s a 50% chance that you won’t be able to fly, you may well be happy to pay the extra $200. If you cancel, you’ll only lose $225 (the extra $200, plus the $25 cancellation fee), whereas if you cancel after opting for the cheaper flight, you’ll lose $600.

Real Options is an application of these principles to software development invented by Chris Matts (see figure 4.17).[4] Chris summarizes the principles of Real Options in three simple points:

4 Chris Matts and Olav Maassen, “‘Real Options’ Underlie Agile Practices,” InfoQ (2007), http://www.infoq.com/articles/real-options-enhance-agility.

Figure 4.17. Real Options lets you reduce risk by leaving your options open.

· Options have value.

· Options expire.

· Never commit early unless you know why.

Let’s look at each of these principles in a little more detail.

4.3.1. Options have value

Options have value because they allow you to put off committing to a particular solution before you have enough knowledge to determine what solution would be best. In the finance industry, the value of an option can be calculated precisely. This isn’t the case in software development, but, in general, the less you know about the optimal solution for a particular problem, the more value there is in being able to keep your options open.

Options also have a price. The price in software development is the effort involved in incorporating this flexibility. This price might involve discussing the possible options upfront, adding layers of abstraction to allow a different implementation to be switched in more easily, making certain parts of the application configurable, and so forth.

For example, suppose that you’re building a new website for a dynamic young startup. The founders have no clear idea of the volume of users they expect; they know it will start small, but they’re very ambitious and expect millions by the end of the year.

You have three options here. You could build the application with no particular regard to scalability, and make it more scalable if and when the need arises, using the YAGNI (“You Ain’t Gonna Need It”) principle. This is fine if the application never scales. But if it does, the refactoring work will be extensive.

Alternatively, you could invest in a highly scalable architecture from the word go. This would avoid rework, but it would be wasted effort if volume remains low.

A third possibility would be to buy an option to scale up later. You wouldn’t implement a fully scalable architecture immediately, but you could spend a little time upfront to see what would be needed to make the initial implementation easily scalable in the future if required. If you don’t need to scale, you’ve only invested a little upfront design time, and if you do, you’ll be able to do so at reduced costs.

4.3.2. Options expire

You can’t keep an option open forever. In software development, an option expires (that is, you can no longer use it) when you no longer have time to implement it before the related feature is due to be delivered. For example, in figure 4.18, you have the choice between two implementations (solution A and solution B). At this point, you don’t know which solution would be best, so you add a layer of code to make it possible to switch to either solution A or B at a later date.

Figure 4.18. Real options expire. Once you pass an option’s expiry date, you can no longer exercise this option.

If you decide for solution A, it will take 10 days to integrate. Implementing solution B, on the other hand, would only take 5 days. In practical terms, this means that if you decide to implement solution A, you must do so at least 10 days before the delivery date, which is when your option on solution A expires. If you delay any further, you won’t be able to exercise this option. You have a bit more time to opt for solution B, as this option only expires 5 days before the delivery date.

Unlike financial options, you sometimes have the power to push back expiry dates. For example, if you can find a way to integrate solution A more quickly, you can leave that option open longer.

4.3.3. Never commit early unless you know why

The third principle of Real Options is simply to defer committing to a particular solution (“exercising the option”) until you know enough about why you’re choosing that solution.

Real Options gives you the possibility to put off making a decision, but the aim is not to systematically delay until the last possible (or “responsible”) moment. Using Real Options, you only delay until you have enough information to act. When you have enough information, you implement your chosen solution as quickly as possible. For example, you may be delaying your decision because solution A is being developed by another team, and you want to wait to see if this library will work well in your situation. In this case, you can wait until the option for solution A expires, but no longer. If the library takes longer than this to develop, you’ll be forced to exclude solution A from your list of options.

But you may choose to act sooner if you can. For example, if your team could build either solution A or solution B, but you don’t know which is the most appropriate, you might choose to build experimental versions of both solutions concurrently. If you obtain enough information to act before the options expire, it makes sense to act sooner rather than later.

To help you learn enough to make sensible design and implementation decisions, you can use an approach called Deliberate Discovery.

4.4. Deliberate Discovery

Deliberate Discovery is the flip side of Real Options, and the two principles go hand in hand. Deliberate Discovery was originally proposed by Dan North[5] and was developed by Liz Keogh and other members of the London BDD community.

5 Dan North, “Introducing Deliberate Discovery” (2010), http://dannorth.net/2010/08/30/introducing-deliberate-discovery.

In software development, ignorance is the constraint. You know a lot more about the best way to build a particular solution after you’ve finished building it, but by then it’s too late to take advantage of your knowledge. You can use the principles of Real Options to put off choosing a particular implementation, or implementing a particular feature or story, until you know enough to make a reasonable decision. But if you’re aware that you don’t know what the best solution is, you can proactively investigate your options in order to make a reasonable decision sooner rather than later. Uncertainty represents risk, and where possible you should hunt out and reduce uncertainty. This is where Deliberate Discovery steps in.

Deliberate Discovery starts with the assumption that there are things you don’t know. This might be something bad that you couldn’t possibly have anticipated and that will pop up and cause you problems at some point during the project. Or it might be an opportunity to innovate: “If only we’d known about that technology earlier, we could have built this feature in half the time.”

Real Options help you keep your options open until you have enough information to act; Deliberate Discovery helps you get this information. If you actively try to increase your knowledge in this area, you can both reduce the risk of uncertainty and make decisions faster; remember, as soon as you know enough to commit to a particular solution, you can choose to exercise your option or not.

But Deliberate Discovery also has broader applications. For example, suppose you’ve decided to implement a particular feature and have broken it down into a number of stories. Some of these stories may seem straightforward, and others may not be so simple.

The natural tendency is to implement the simplest stories first, and there are good reasons why you might do this. But reducing your ignorance should be high on your priority list. Wherever possible, identify the stories that involve the most uncertainty, and tackle these ones first. Then review the remaining stories, keeping in mind what you’ve learned and considering the feedback the stakeholders give you. This simple approach can go a long way in helping you increase your knowledge and understanding in areas that matter.

Exercise 4.3

Raj, Joe, and Susan used both Real Options and Deliberate Discovery to decide on the best way to implement the password-strength feature. Discuss how.

4.5. From examples to working software: the bigger picture

In BDD, conversations around an example mark the first step in actually building and delivering a feature or story. You don’t have this conversation until you’re committed to implementing the corresponding functionality. But once you do, you kick off a process that will hopefully lead to putting a useful new feature in front of your users (see figure 4.19).

Figure 4.19. From examples to working code

The process starts when you choose a story to work on and select one of the acceptance criteria to implement . Next you discuss this acceptance criterion with the relevant stakeholders, using examples to explore the problem space, as we discussed in the previous section . These conversations should produce a better understanding of what the user needs, and a set of examples, or scenarios, to illustrate the acceptance criterion.

Different types of conversations

In practice, conversations about features and examples can take many forms. For example, teams that are new to BDD often benefit from workshops early on in the iteration, where the whole team, including business stakeholders, is involved. These workshops are a great way to get communication happening sooner rather than later, to give the team a shared understanding of the features they’re building, and to produce a set of high-quality examples. On the downside, they can be hard to organize and are expensive in terms of people-hours.

A more lightweight approach, which can work well when teams start to become more experienced in BDD, is known as the “Three Amigos.” Three team-members—a developer, a tester, and a business analyst or product owner—get together to discuss a feature and draw up the examples. For this to work well, all three need to be reasonably familiar with the problem space, but the dynamic interaction of each role is often very productive. The tester, with great attention to detail and a focus on validation, will propose obscure edge cases and often point out scenarios that the other team members have missed. The developer will point out technical considerations, and the business analyst or product owner will be able to judge the relevance and relative value of the different scenarios. In addition, the developer will gradually obtain a much deeper understanding of the business requirements than would normally happen in a more traditional project, and this understanding becomes more and more useful as the project progresses. Often, in this approach, the three will sit around a computer and write up an initial draft of the automated scenarios together. This helps reduce the risk of information loss later on down the track.

In some teams, the business analyst prefers to do the bulk of the scenario writing, referring to stakeholders if they have any questions. This approach doesn’t build a shared understanding as effectively as the previous strategies, but it can be made to work. The scenarios should be prepared by the business analyst but then reviewed with a developer and a tester. Developers can provide useful feedback on how best to express the scenarios to take advantage of the language features of the automation tooling. And testers can provide valuable input about additional scenarios that might need exploring.

You convert these examples into a slightly more structured format , known as scenarios, so that you can automate them in the form of automated acceptance tests. Naturally, this test should fail at first , because you haven’t implemented anything yet. The developers now proceed to write the code required to make this acceptance criterion pass . The developer uses TDD, or more precisely, BDD at a unit-testing level, to implement the various layers needed to deliver the requested functionality. We’ll discuss how to write and automate these scenarios in the next chapter.

If the developer has worked well, the acceptance criterion should now pass , which indicates that you’re done with this scenario and can move on to the next one . When all of the scenarios pass, the developers are done with this story . QA can now use the passing automated acceptance tests as a basis for their exploratory testing, and stakeholders can review the new feature to see how well it matches their expectations.

4.6. Summary

In this chapter, you learned how to describe and organize features and how to illustrate them with examples. Along the way, you learned about the following:

· A capability enables some business goal, regardless of implementation.

· A feature is a piece of deliverable software functionality that provides users with a capability.

· Large features can be broken down into smaller features to make them easier to organize and deliver.

· Agile projects use user stories to plan and deliver features.

· Concrete examples help you build up a shared understanding about a feature.

· The principle of Real Options recommends that you shouldn’t commit to a particular solution until you have enough information to be confident that it’s the most appropriate one.

· Deliberate Discovery points out that one of the biggest risks in any software project is your own ignorance, and that you should actively aim to identify and reduce uncertainty wherever you can.

A surprising number of the benefits of BDD come from simply having a conversation with the business, using examples to challenge assumptions and build a common understanding of the problem space. One of the principle benefits of BDD is to encourage and structure this kind of conversation. But there’s also a great deal to gain by automating these examples, in the form of automated acceptance criteria. In the next chapter, you’ll learn how to express clear, precise examples in a structured format, and how to turn these examples into executable specifications that can be read by tools like JBehave, Cucumber, and SpecFlow.