Requirements Management

Managing Non-Functional Requirements in SAFe

 Managing Non Functional Requirements in SAFeManaging non-functional requirements (NFR’s) in software development has always been a challenge. These “system capabilities”, such as ‘how fast a page loads’, ‘how many concurrent users the system can sustain’ or ‘how vulnerable to denial-of-server attacks can we be", traditionally have been ascribed as belonging to “quadrant four of the agile testing quadrants” of Brian Marick. That is, these are tests that are technology facing and which critique the product. That said, it has never been clear *why* this is so as this information  can be critical for the business to clearly understand.

In the Scaled Agile Framework (SAFe) NFR’s are represented as a symbol bolted to the bottom of the various backlogs in the system. This indicates that they apply to all of the other stories in the backlog. One of the challenges of managing them lies in at least one aspect of our testing strategies: When do we accept them if they represent a "constant" or "persistent constraint" on all the rest of the requirements?

This paper advances an approach to handling NFR’s in SAFe  which promotes the concept that NFRs are more valuable when considered as first class objects in our business facing testing and dialogs. It suggests that the business would be highly interested in knowing, for example, how many concurrent users the system can sustain on-line.  If you're not sure about this just ask the business people around the healthcare.gov project! One outcome of this approach is that we see a process emerge that reduces or need to treat them as a special class of requirements at all.

If we expose the NFR’s to the business, in a language and manner that would create shared understanding of them, we could avoid surprises while solving a major challenge.

Please consider the following Gherkin example:

Feature: Online performance

In order to ensure a positive customer experience while on our website

I’d like acceptable performance and reliability

So that the site visitor will not lose interest or valuable time

Scenario: Maximum concurrent signed-in user page response times

  • Given there are 1,000 people logged on
  • When they navigate to random pages on the site
  • Then no response should take longer than 4 seconds

Scenario: Maximum concurrent signed-in user error responses

  • Given there are 1,000 people logged on
  • When they navigate to random pages on the site for 15 minutes
  • Then all pages are viewed without any errors

These are pretty straight-forward and easy to understand test scenarios. If they were managed like any other feature in the system the creation, elaboration and implementation of them would serve as a ‘forcing function’  where derived value in the form of shared understanding between the business and the development would be gained. As well these directly executable specifications could be automated such that they could run against every build of the software. This fast feedback is very important to development flow. If we check in a change, perhaps a configuration parameter, or new library, that broke any NFR, we’d know immediately what changed (and where to go look!).  Something that is also very valuable (and often overlooked!) is that each build serves as a critical on-going baseline for comparison of performance and other system capabilities.

Any NFR expressed in this fashion becomes a form of negotiation. It makes visible economic trade-off possibilities that might not otherwise be well understood by the business. For example, if push came to shove, would there still be business value if, under sustained load, page responses were sometimes reduced to 5 seconds in some cases?

Another benefit of writing the test first is that it would increase the dialog about *how* we will implement the NFR scenario helps to ensure, by definition, that a "testable design" emerges.

This approach to requirements/test management is known as "Behavior Driven Development" (BDD) and "Specification By Example". The question of how and when to implement these stories in the flow sequence remains a challenge and the remainder of this article addresses this challenge directly. I’ll address one solution in SAFe.

The recommendation is to Implement the NFR an an executable requirement using natural language tools like Cucumber, SpecFlow (which supports Gherkin) or Fit/FitNesse (which uses natural language and tables) as soon as they are accepted as NFRs in an iteration as part of the architectural flow. Create a Feature in the Program backlog that describes implementation of the actual NFR (load, capacity, security etc.) and treat it like any other feature that point. Have the system team discuss, describe and build the architectural runway to drive the construction of the systems that will support the testing of them. Use the stories as acceptance against the architectural runway, if that is appropriate. If you do not implement the actual test itself right away (not recommended) at least wire it up to result in a “Pending” test failure (not really recommended but I’ll describe that more in a moment). When the Scenarios are running in your continuous integration (CI) environment, the story can be accepted. With regards to your CI, keep in mind that some of these tests, with large data sets or with long up time requirements will take a while to complete so it is very important to separate them from your fast failing unit tests.

The next important step is to make these tests visible to the business and to the development team. To the business, one way to make them visible, along with your other customer facing acceptance tests, is you use a tool like Relish that can publish them, along with markup and images as well as navigation and search.

Another recommendation in this approach would be to build a “quality” dashboard using the testing quadrants as described earlier. That is, each quadrant would report a pass/fail/pending status that could be used for governance and management of the system. When all quadrants are green, you can release. You can get quite creative with this approach and use external data sources, such as Sonar and Cast (coverage and code quality tools, respectively) and even integrate with Q3 exploratory testing results, for example. There is work to be done in this area. Hopefully someone will write a Jenkins plugin or add this to a process management tool.

Using this approach you will always know what the status of your NFR’s are and get the information you need in a timely fashion, when there is still time to react. This approach would help to eliminate surprises and remove the need for a major (unknown cost) effort at the end of your development cycle. In the case above, even if these tests had been marked “Pending” you’d have the knowledge that the status of these NFR’s were unknown, which would increase trust and share the responsibility across the entire value stream.

Learn more about the Scaled Agile Framework: download SAFe Foundations.

Learn more about our Scaled Agile Framework Training and Certification Classes.

Use Case 2.0 – Slices and Relationships: Extension

Since the introduction of Use-Case 2.0 we have received a number of questions about use-case slices and in particular how they relate to the concepts on include, extend and generalization. In this blog we will look at the impact of the extend relationship on use-case slicing.

What’s the Problem?

An extend relationship can be used to factor out optional behaviour from a use-case narrative. It is particularly useful in the following situations:

  1. Where the optional behaviour will be part of a separately purchased extension
  2. Where different customers require different variations of the same behaviour
  3. Where already implemented use cases need to be extended
  4. Where additions need to be made to previously frozen or signed off use cases

Consider a hotel management system with which customers can make online room reservations. As shown in figure 1, the primary use cases would be “Reserve Room”, “Check In Customer” and “Check Out Customer”.

Use Case 2.0 – Slices and Relationships: Extension

Figure 1 – Hotel Management System Use Cases

Now let’s consider what happens if the hotel management system being built is to be a modular commercial product with an optional waiting list feature. This feature allows a customer to be put on a waiting list in the case where the room they like is already booked. The customer will then be informed when the room becomes available or can have the room reserved automatically within a given timeframe. This feature could easily be captured within use case “Reserve Room” but since it is an optional feature, it is factored out into an extension use case.

Use Case 2.0 – Slices and Relationships: Extension

Figure 2 – The re-factored Reserve Room Use Case

Now, to provide a little more context, let’s first have a look at the use-case narrative of the original Reserve Room use-case.

Use Case 2.0 – Slices and Relationships: Extension

Figure 3 – Reserve Room use-case narrative

Without the extending use case we would have had only one use case to slice up - Reserve Room.  Consider the following example Reserve Room use-case slices.

Use Case 2.0 – Slices and Relationships: Extension

Figure 4 - Use-case slices for the Reserve Room use case

The question now is what will happen to these slices when we make use of extension:

  • Does an extending use case have its own use-case slices?
  • Does using extend change the number of use-case slices?
  • Does using extend have an impact on any existing use-case slices?

Does an extending use case have its own use-case slices?
The answer is yes. Using extend means that we move behaviour from one use case to another; we start by literally cutting and pasting text between the two use-case narratives. More specifically we take out one or more alternative flows and place them in a use case of their own. In this case the Alternative Flows AF16, 17, 18 and 19, which are all about the waiting list, would be moved to the new Handle Waiting List use case.

We could have left all the behaviour related to handling a waiting list in the Reserve Room use case. By using extend we have made optional behaviour explicit. In the case of extension the extending use case is performed in the context of the original use case but without the original use case’s knowledge. This means that any use-case slice that requires behaviour of the extension use case must belong to the extension use case. So, extension use cases do have their own use-case slices

Does extension change the number of use-case slices?
Before refactoring we had one use case with its set of use-case slices. The question is what will happen to this set when we factor out the optional behaviour using the extension. Most likely the total number of use-case slices will remain the same because any alternative flow significant enough to get moved to an extension use-case would probably have got its own slice or slices.

Does extension have an impact on the use-case slices?
Yes and no. Yes, because in the use-case slices we must refer to the right flows of the right use cases;   the original use case or the extension use case. No, because the stories and test conditions remain the same independent of the use case they belong to.

Some Examples

Let’s first have a look at the refined narrative of the Reserve Room use case and the narrative of the Handle Waiting List use case

Use Case 2.0 – Slices and Relationships: Extension

Figure 5 – Updated use-case narrative

And below you will find use-case slices from the extending Handle Waiting List use case

Use Case 2.0 – Slices and Relationships: Extension

Figure 6 - Use-case slices of the Handle Waiting List use case

Notice that in the example use-case slice above:

  1. The basic flow of the Reserve Room is always required because the Handle Waiting List (extension) use case cannot be performed without it.
  2. Alternative Flow 16 of the original Reserve Room use case has become the basic flow of the  Handle Waiting List (extension) use case.
  3. Alternative Flow 17, 18 and 19 of the original Reserve Room use case have become Alternative Flow 1, 2 and 3 respectively of the Handle Waiting List (extension) use case.

Final words

So, as you can see use-case slices are as effective for use cases and use-case models that use the extension mechanism as those that don’t.  In the next blog in this series we will examine the effect of the generalize relationship on the slicing of the use cases.

This post was co-authored with Ian Spence.

Useful links:

Use Case 2.0 Training Classes

Use Case 2.0 – Slices and Relationships: Inclusion

Since the introduction of Use-Case 2.0 we have received a number of questions about use-case slices and in particular how they relate to the concepts of include, extend and generalization.

In this blog we will look at the impact of the include relationship on use-case slicing.

What’s the Problem?

An include relationship is used when two or more use cases share common behaviour. This is then factored out into a separate use case.

Consider the case where we have two separate use cases Register Birth and Register Change of Address. Even though both use cases are concerned with registration these are separate use cases because  the flow of events and the business rules are quite different. They share however common behaviour. Both include a description of all the ways a case worker can find a citizen when registering births and address changes. As shown in Figure 1, the common behaviour can be re-factored  into a single Find Citizen Use Case that is included in both of the original use cases.

Use Case 2.0   Slices and Relationships: Inclusion

Figure 1 – The re-factored use-cases

Before the re-factoring it was very easy to slice up the original two use cases. The question now is what will happen to the use-case slices when we make use of inclusion:

  • Does an inclusion use case have its own use-case slices?
  • Does inclusion change the number of use-case slices?
  • Does inclusion have an impact on any existing use-case slices?

Does an inclusion use case have its own use-case slices?
Inclusion means that we move behaviour from one use case to another; we literally cut and paste text between the two use-case narratives. However, this does not mean that we move compete stories or use-case slices. This is because an inclusion use case is never performed on its own. In the above example the Register Birth or the Register Change of Address use cases are in control of when the Find Citizen use case is performed. Because an included use case is never performed independently of its including use case it does not have its own slices. This means that all the slices remain in the original use-cases, and that the included use-case does not have use-case slices of its own.

Does inclusion change the number of use-case slices?
Before refactoring we had two use cases and each use case has its own set of use-case slices. So what will happen when we factor out the common behaviour using the inclusion mechanism? Because an included use-case does not have use-case slices of its own, the total number of use-case slices remains the same. Each of the original use-cases keeps its original number of use-case slices.

Does inclusion have an impact on the use-case slices?
The use-case slices of the original use-cases are indeed impacted. Before refactoring the original use-case slices referred to flows contained within one use case. After refactoring the use-case slices of the base use-case refer to flows in two use cases: 1) the original use-case and 2) the included use-case.

Note: if new flows are added to the included use cases then new slices will be needed in all of the original use cases.

Some Examples

Use Case 2.0   Slices and Relationships: Inclusion

Figure 2 – Example Basic Flow use-case slices

Before inclusion all required behaviour for slice #1 of the use case Register Birth and slice #1 of the use case Register Moving House was contained in their respective basic flows.  After inclusion these slices reference the basic flow of their original use case and the basic flow of the Find Citizen use case. This is indicated in the slice by stating the name of the use case in front of the flow, in this case Find Citizen.BF.

Use Case 2.0   Slices and Relationships: Inclusion

Figure 3 – Example Alternative Flow use-case slices

Before inclusion all required behaviour for slice #2 of use case Register Birth and slice 2# of use case Register Change of Address was contained in their respective basic and alternative flows. The goal of the alternative flows is to handle finding citizens that are residents of different municipalities. After inclusion these slices required require the basic flow of their original use case, the basic flow of the Find Citizen use case and alternative flow 1 of the Find Citizen use case.

If it doesn’t affect the number of slices why both with includes?
The benefits of re-factoring a use-case model to use includes are not changed by the use of use-case slices. They can still make the model easier to understand and maintain, and provide clues to the developers that the included behaviour will be re-used in different circumstances.

Final words
So as you can see use-case slices are as effective for use cases and use-case models that use the inclusion mechanism as those that don’t.  In the next blog in this series we will examine the effect of the extends relationship on the slicing of the use cases.

This post was co-authored with Ian Spence.

MoSCoW Anxiety

According to Wikipedia MoSCoW is a prioritization technique and a core aspect of agile software development. Its purpose is to focus a team on the most important requirements, for example to meet a deadline.

I know of many project teams that struggle using this technique because their stakeholders are unwilling to do the prioritization or accept the technique itself. If you have participated on a project where all requirements were classified as must have, I am sure you know what I mean.

What can you do when this happens to you? Well, valid options that might come to mind are run and hide and performing a coup for a decent Product Owner. However, before you go to extremes you might want to try another option first.

Basically what we have here is a kind of anxiety, MoSCoW anxiety if you will.  Anxiety? Yes!  In my experience many stakeholders simply become afraid they will not get what they have asked for when they are asked to classify requirements below the must have level. This makes perfect sense when you reckon that many projects deliver only a (small) part of the promised functionality and a lot of stakeholders have felt let down by IT at least a number of times. Read More

Dutch post: Meer heldere requirements: Kies de juiste verpakking

Mijn collega Kurt Bittner heeft afgelopen juni  tijdens IBM Innovate 2010 (Florida) zijn visie gegeven op de nieuwe rol en verantwoordelijkheden van de nieuwe generatie informatieanalisten. Wanneer je geen kans hebt gezien om zijn presentatie bij te wonen, bekijk die dan via Slideshare: Transforming the role of the Business Analyst. Hieronder volgende enkele observaties of veel voorkomende problemen die hebben geleid tot zijn visie:

  • Gebruikers verwachten andere  functionaliteit dan waar ze oorspronkelijk om hebben gevraagd.
  • Gebruikers eisen functionaliteit die ze nooit zullen gebruiken
  • Gebruikers geven tegenstrijdige of conflicterende requirements Read More

Stimulating a discussion: Getting to needs

Stimulating a discussion: Getting to needsOne of the frequent questions we are asked is "how can I get the time to explore needs when the business says that it is already done - "it's in the business case", even when it is obviously not complete?  This is actually a pretty common occurrence - nobody wants to take time to understand needs because they think it has already been done. Read More

Dutch post: Meer heldere requirements: vermomde processen

De laatste paar dagen hebben verschillende mensen mij dezelfde vraag gesteld: “Hoe kunnen we meer heldere requirements krijgen”. Hoewel ik het eens ben dat het niet netjes is om een vraag met een vraag te beantwoorden, is het in mijn visie beter om in dit geval soepel om te gaan met die etiquette. En wel  omdat deze vraag eigenlijk niet zo eenvoudig te beantwoorden is. Bijvoorbeeld, waarom is dit nodig en welk probleem lost het op? Of, wat bedoel je precies met helder? En heb je heldere requirements en wil je er meer? En in dat geval, meer dan wat? Of heb je requirements die niet helder zijn en die je beter wilt kunnen communiceren. En zo ja, hoeveel beter?

Je zou kunnen zeggen dat dit gewoon spelen met woorden is. En dat klopt! Maar is het formuleren en communiceren van requirements niet feitelijk hetzelfde? Voor meer heldere requirements zijn een tal van zaken benodigd. Er is echter een belangrijk element dat vaak over het hoofd wordt gezien, namelijk inzicht in de structuur van taal en de wijze waarop taal wordt geïnterpreteerd. Read More

Attitudes Toward Delivering Business Value

Traditional software development projects are executed in a value-neutral setting in which:

  • Every requirement is treated as equally important
  • The delivery of technical components is seen as of equal importance to the delivery of usable systems
  • "Earned value" systems track project cost and schedule, not stakeholder or business value
  • A "separation of concerns" is practiced, in which the responsibility of the development team is confined to turning software requirements into verified code rather than delivering business value
  • The actual desired outcomes of the project are ignored in favor of implementing the largest number of requirements possible

No wonder so many projects fail to deliver the desired business results! Unfortunately this includes many iterative software development projects where the developers iteratively implement the requirements rather than delivering business value. Any management system that rewards things that are easily measured (like implementing requirements) without a clear and direct tie to business value delivered is headed down the wrong path. Read More

More accurate requirements: when process is lost

More accurate requirements: when process is lostOver the last few days a number of people have asked me the same question: “How can we get more accurate requirements?” While I agree it is not nice to answer a question with a question, in this case you might bend etiquette a bit because in reality this question can be hard to answer. For example, why is it necessary and which problem does it solve? Or, what exactly do you mean with accurate?  And do you have accurate requirements and you want more of those? And in that case, more than what? Or do you have inaccurate requirements which you want to become more accurate? And if so, how much more?

You might say: “Hey, that’s just playing with words”. Well, that’s right and so is writing and communicating requirements. In order to get accurate requirements you need a number of things. However, an often overlooked element to writing accurate requirements is understanding the structure of language and how language is perceived. Read More

What is an Iteration?

What is an Iteration?

Iteration: A self-contained mini-project, with a well-defined outcome: a stable, integrated, and tested “release”. Let’s look at the three aspects of this definition in more detail.

A software development project produces a new release of a software product by transforming a set of users’ requirements into a new or changed software product. With an iterative and incremental approach, this process is completed little by little, step by step, by splitting the overall project into several mini-projects, each of which is called an iteration.

From the perspective of the development team, each iteration can be considered to be a self-contained
project. This approach is very powerful because it enables the development team members to focus on meeting their immediate objectives and ensures that the results generated are frequently and objectively measured. The management team needs to ensure that the iteration objectives form
a credible part of the larger overall project.

The management team needs to reinforce this way of working by ensuring that each iteration has the following:

Read More

Page 1 of 212