Old Way: Time-Tested and Still In Use
As we've seen, getting software to provide business value to a customer is hard. Making sure that the software we produce actually provides the customer with the business value that they need is even harder than that. In order to maximize the chances of producing something the customer actually needs, we must have some idea of what that will look like. In addition, we need to have some way of testing if we have built the right thing, then to ensure we have built the thing right. This is one of the main functions of requirements.
|
Back in the olden days, when software engineering was a relatively young discipline, the Waterfall
method dictated that there must be a document that contains a listing of all the parts that the
software would contain, along with an itemization of what all those parts would do. The software
documentation was kept in a bit notebook called a software development file
or SDF. There were quite a few documents in that set [see here for a typical listing]. The key document section for this discussion from this example is the one in section 5.0. |
The Requirements Document is intended to capture the low-level requirements for the project, and to elaborate the details of the contract between the customer and the developer regarding the completed project. Requirements are intended to show what the system is going to do, in an itemized and provable way. Requirements are selected so as to decompose the system operation into individual pieces, and normally each requirement is numbered to facilitate this situation. The numbers are used to track the method of verification, to prove that the software meets the requirements and does what it's supposed to do. (The shorthand for this is the expression "works as advertised".)
The number of methods for determining what to list as system requirements is quite large. The topic of requirements analysis has been covered by many books and many more websites. It seems everyone has her own method, and everyone feels her method is best. However, it all boils down to the simple fact that the system operation must be specified in a very detailed fashion, so that all the operations are listed, and so that they can be proved to be correct. Check out the analysis page for a few more details on the subject.
For Waterfall, the Software Requirements Specification [SRS] has the format for which an outline is
provided below. The general idea is to itemize all the functional and performance requirements of the
system, using shall
statements. Focus on what
the system will do, not how
it will do it. There is a tendency when writing requirements to include some design decisions as a part
of the document; this urge should be resisted.
Note that there are two critical sections in the SRS: the Functional
requirements and the
Performance
requirements. The difference between these is the dividing line between what
the project needs to do to function properly [e.g., the system shall provide
clickable buttons for…
] and what the project needs to do to operate
properly [e.g., the system shall … when the 'CLEAR' button is clicked.
].
5.0 Requirements Specification
5.1 Introduction
5.2. CSCI Component Breakdown
5.3 Functional Requirements by CSC
5.3.1 Functional Requirement 1
.
.
.
5.3.n Functional Requirement n
5.4 Performance Requirements by CSC
5.4.1 Performance Requirement 1
.
.
.
5.4.n Performance Requirement n
5.5 Project Environment Requirements
5.5.1 Development Environment Requirements
5.5.2 Execution Environment Requirements
What, pray tell, is a "CSCI"???
CSCI stands for Computer Software Configuration Item
and is the top level of the
software divisions. The CSCI is usually the name of the software application. It comprises Computer
Software Components, or CSCs, each of which is made up of Computer Software Units, or
CSUs. A CSU is composed of modules. So, there is the hierarchy of the different parts.
For example, let's say your project is a database application with a GUI client front end written in Java,
and a server written in a scripting language like Ruby. Further, let the server have several flavors
based on the type of information to be extracted from the database; these servers will be dynamically
started as they are needed, and shut down at the end of each service performed. This program is called
BarnDoor, for unknown reasons. The module hierarchy in this section of the requirements document might
appear as follows:
5.2 CSCI Component Breakdown
CSCI BarnDoor is composed of the following CSCs:
5.2.1 GUI Client CSC -- <put a brief description of the GUI client here>
5.2.1.1 Client Main Screen CSU -- <put a brief description here>
5.2.1.2 Client Input Panel CSU -- <put a brief description here>
5.2.1.2.1 InputPanel module -- <put a brief description here>
5.2.1.2.2 GUIbutton module -- <put a brief description here>
5.2.1.2.3 ColorExtend module -- <put a brief description here>
5.2.2 Server CSCs -- <put a brief description of the server here>
5.2.2.1 Ruby Server CSC -- <put a brief description of the Ruby server here>
5.2.2.2 Java RMI Server CSC -- <put a brief description of the Java RMI server here>
5.2.2.3 C-sharp Server CSC -- <put a brief description of the C-sharp server here>
.
.
.
5.2.3 Database CSC -- -- <put a brief description of the GUI client here>
.
.
.
The introduction to the functional section should describe the features that the completed system can be
expected to have. It should describe what the completed system will do. Avoid describing how it will
be accomplished. Implementation details will be included in other documents. The rest of this section
will be divided into sub-sections, one for each of the parts or CSCs of the system. In fact, using the
CSCs that are defined in the previous section of the SRS is a good way to show the way the system is
divided up, known as the functional decomposition
of the system.
Each subsection should reference a particular functional requirement group. Each functional requirement in a subsection should be given a meaningful name which describes the requirement. For example, if the first functional requirement group is to provide the graphical user interface to the system, then the first subsection might be labeled:
5.3.1 Graphical User Interface [GUI] Subsystem
A brief description of the functionality [1-2 paragraphs, as needed] would follow, as the introduction
for the functional section. After that would come the individual, specific, detailed requirements
statements for the GUI part of the project. All requirements must be structured in the shall
statement
format, and must be numbered. For example, here are some suggested requirements
statements for a typical GUI:
5.3.1.1 The GUI subsystem shall display a window for the main application.
5.3.1.2 The GUI subsystem shall display a window to provide details of operation (a "help" window).
5.3.1.3 The GUI subsystem shall react to mouse clicks on displayed buttons.
5.3.1.4 The GUI subsystem shall include a menu bar at the top of the main window.
5.3.1.5 The GUI subsystem shall provide the facility such that the operations which are available via graphical
button clicks are also available via menu selections using the keyboard.
5.3.1.6 The GUI subsystem shall provide text entry fields into which the user may type values.
5.3.1.7 The GUI subsystem shall provide error checking on the text entry fields such that the user is
provided immediate feedback in case of erroneous entry.
Notice the detail and specificity of each statement, which addresses a very particular operational
requirement. It's not The GUI shall display a window
, rather, it is The GUI shall display a
window for the main application
.
These are very simple examples. For a major software development effort, the SRS might be more than 100 pages long, with at least 1000 requirements statements. The Performance Requirements section would contain a similar listing of requirements, in the same formalized language.
It is easy to see, from this simple example, how the requirements portion of the documentation alone for
a Waterfall project will consume a considerable amount of resources for the project at the start, and
will probably need to be revisited several times during the course of the project to make sure that all
the changes which have occurred during the life of the project have been accounted for and incorporated
into the document. If this does NOT occur, the SRS will not accurately reflect what has been built;
this is known as proscription
versus description
.
There is a LOT more to say about requirements in the Waterfall process; entire books
have been written about just THIS PART of the software development process, which is known as the
requirements elicitation process
. However, this is enough of an
overview to show you why the Agile focus is different [and many people say better
].
Agile works in a completely different way than Waterfall. Instead of trying to document all of the parts of a complex system up front, meaning at the very beginning of the project, Agile simply gets the team to figure out what the main parts of the system are, then pick a few of them that are key to providing value to the customer. The team then designs and builds that one key part or feature, then adds more parts and details to it as time goes on. Further, the requirements are focused on meeting the needs of the user or customer, on delivering immediate business value, and on inviting collaboration.
In software engineering, as in many other disciplines, gathering requirements is called
requirements elicitation. This process collects the requirements and combined them
into a document of some form. As we've seen in Waterfall, this is a Software Requirements
Specification or SRS
. However, in Agile/Scrum, the requirements take the form of things
called user stories. This name is not chosen by accident. The idea is to
have the customer walk the team through a typical use scenario, with each of the steps being written
down so that at the end, the team [and the customer/user] will have a complete story
of what
that portion of the software must do. This helps the team to know:
valueof the software or feature so that the team can thoroughly understand what the request is being driven by
With Agile, as with Waterfall and requirements statements, there is a very specific format for the user
stories. However, the format is much more user-friendly
:
As a <type of user>, I want <some goal>, so that <some reason>.
Here's how the parts in angle brackets are described:
whatfocus of requirements in Waterfall. The developers must fully understand the feature request in order to build the right thing.
Here is an example from your text book on page 116 which shows how this would look for the case of our weather application:
As a concerned and retired grandmother, I want to receive alerts for areas where my children and
grandchildren live so I know when I need to worry and call them to make sure they are safe.
This user story clearly defines all three of the items in the list: type of user [grandmother], what is wanted [alerts], and the reason it is wanted/needed [so I know to call them]. The who, what, and why make a very specific combination so that the developers have much more to work with than the traditional way of Waterfall requirements — they have context for this part of the software. This helps to insure that the team will build the right thing.
A user story is not a specification, but a communication and collaboration tool. User stories should
not be handed off to the development team but be complemented by a conversation.
[Pichler 2010, in
Ashmore, p 117]
There is a handy acronym to remember which will help you make good user stories: INVEST, which is defined as follows:
coupledto other activities to the greatest extent possible.
so thatclause.
More often than not, a user story will start out being too large to be effective. In this case, they
are known as epics
. An epic is simply a user story which is too big
to be effectively designed, coded, and tested within a single sprint. The name comes from literature,
in which the idea of a long, intricate story or [usually] a narrative poem is called by that name.
As time goes on in the project, the PO and the development team must re-visit the user stories to
determine which ones will be part of the next sprint. Part of this exercise is to realize that the
epics need to be broken down into smaller parts, called child stories
. There are
usually quite a number of child stories for each parent epic. This is a GOOD thing, since you have to
start with the bigger idea and then break it into successivly smaller and smaller parts until you get
the user stories that result to be the size that can be done in a single sprint. This process [again]
is often known as functional decomposition
. Working in this manner, the team
can discover all of the detailed design decisions that will be needed to deliver that particular set of
user stories.
If a user story or epic is not going to be part of a sprint for more than three months, it can
be put on the As an example, consider the scenario of a Thanksgiving Dinner application. The initial
requirement may be given as |
|
There is a key word which discribes the level of detail that is involved with the size of user stories,
or requirements too, for that matter; the word is granularity
. This is not an
official
term, but is one that is used a lot in industry to describe the level of detail. For
example, an epic would not be something that can be completed in a single sprint; it must be broken down
into a finer granularity
so that it can be handled effectively.
Another way of looking at user stories is to define them from use cases
. This is
a concept from UML which can be helpful in getting a start on the user stories. A use case is a set of
scenarios that can be used to show what can (or should) happen in a system. It is a formalized
implementation of typical interactions in the system. A scenario is a sequence of steps which shows what
happens between a system and its users.
Suppose you are cooking dinner from a recipe. You have a certain set of steps, which, if followed properly, will result in a good dinner. However, the recipe is like an algorithm, and it assumes there are certain other parts that you already have, which make up the cooking system. The recipe might say:
This assumes that you have a stove, a pot with a lid, the rice, a measuring cup, and maybe a timer. All these items, plus you (the user) make up the rice cooking system. So, a scenario for this system might be the following:
The user puts 2 quarts of water into the pot and places the pot on the stove. The user turns on the stove to "high". The stove heats the water to a rolling boil. The user adds 1½ cups of rice to the pot, reduces the heat to low, and covers the pot. Eighteen minutes elapse on the timer. The user opens the pot and checks the water. If the water is gone the user eats the rice.
A use case for this scenario might appear as follows:
Name: COOK RICE
Summary: User puts rice and water into pot on stove, heat cooks rice
Actors: User, Stove
Start State: Stove is plugged operational, and is off
Description of operation:
1. User puts 2 quarts of water into the pot
2. User puts the pot on the stove
3. User turns stove on "high"
4. Stove heats water to rolling boil
5. User adds 1½ cups rice to pot
6. User reduces heat to low
7. User covers pot
8. Stove cooks pot contents
9. Timer counts for 18 minutes
10. User opens pot and checks water level
End State: Rice is done, stove is off, user is eating
Some Alternative scenarios might appear thus:
ALTERNATIVE: Water gone too soon
At step 4, if user doesn't watch for rolling boil
Stove boils away all water from pot
ALTERNATIVE: Water not gone
At step 9, if water is not gone
User puts top back on pot and stove cooks pot contents longer
ALTERNATIVE: Water gone too soon
At step 9, water has been cooked away too fast
User swears a blue streak and cleans burned rice from pot
There are existing systems that will let you enter a user story and then write the child stories under the parent. There are other tools, as well. Having the right tool for tracking parent epics and their resulting child stories can be very helpful to good communication and discussions on the project.
It is extremely important to define exactly what criteria will be used by the team [and the customer] for acceptance of the product. First of all, we want the customer to be happy with the product we have produced. Secondly, we want to get paid! If we do not define the acceptance criteria properly, either one or both of those desires may not be met.
The easiest way to grasp acceptance criteria is with an example, as found in your book on page 120. If you are baking a pie for your dinner, the acceptance critieria might be as follows:
Having criteria at this level of detail provides the development team with specific goals and information about what they must accomplish. Further, the goals are written in a way that can be tested effectively, to prove that they have been met. We shall see more about testability later.
Quick Quiz: Is this a good acceptance criteria: The web
page has buttons.
If it is, why is it good? If not, how can it be improved?
There are several things that can be done to make user stories as effective as possible. These best
practices
are derived from many years and many projects, and provide a guideline for getting the
most bang for your buck. Remember, though, that not every PO is going to know how to write good user
stories without some practice – like everything else in life, it takes practice!
It also takes effective collaboration which requires good communication.
The first thing to note about Best Practices is to have a VERY well-defined idea of who is
responsible for what part of the project. In Agile, the PO is the one responsible for making
sure that the team builds the right thing. This is the In software engineering, there are two terms that go along with these two perspectives. Building the right thing can be tested by a process known as validation, while building the thing right can be tested by the process called verification. Although these two terms may seem synonymous, they are not. These two activities are critical components of many quality management systems in use today. Validation is more of a requirements and design assessment activity. When you check to ensure
you are meeting the needs of the customer, so that the product meets a set of operational
needs, you are ensuring you are building the |
|
Verification, on the other hand, is intended to CHECK the product after it is built to make sure that
it performs correctly and meets the requirements. This part of the process most frequently involves
significant testing to prove that things are working as advertised
and that there are not any
faults or errors with the product. Often this is done using formalized testing methods, which in the
Waterfall method [of course] requires several documents. Agile and its TDD approach helps to remove
the documentation requirements by using continuous integration, short sprints, and
minimum viable products.
Although the terms are very similar, you can remember them easily with the following mnemonic. The
term validation
comes alphabetically before the term verification
, and the process of
requirements and design comes before building the product. So, validation of the requirements comes
before verification of what is built. Another way to look at it, first comes build the right
thing
[validation], then comes built the thing right
[verification].
As part of this idea of responsibility, there needs to be agreement on what is the appropriate amount of detail for the users stories. For this part, the entire team should be involved, since it is the development team who will be working from the user stories that result in order to produce the end result. If there is insufficient detail, the team may not have all the information they need to get the product working properly. If there is too MUCH information the team may be bogged down implementing something that is at too fine a granularity; there is a risk of the user story specifying the HOW not the WHAT, which may confuse the development team.
Almost all user stories start out as epics. That makes perfect sense, given that the customers and the
users will be describing how things work, and it will start out with the general idea of the operations
of the organization. From there, it is up to the team to break these epics down into smaller
user stories that are more manageable. It takes discipline and practice to get this right, and it
requires strong collaboration to make the user stories have the proper amount of detail
so that the team can build them, but not SO MUCH detail that there is too fine a granularity. The trick
is to create these child stories
from the epics so that then capture
the subtleties of the epic and provide the team with usable information to build the right thing.
Let's take a look at an example from your text book on page 122 - 123 using the weather application.
|
|
In the Waterfall method, these child stories would be called derived requirements
, since
they are derived from the main requirement of the epic. This functional
decomposition
[which we've discussed previously in class] brings to light several elements of
the problem that are not apparent from the initial statement. In fact, they can ONLY be uncovered when
the busy executive
is actually COMMUNICATING with the team to express her desires precisely. If
the team tried to build this part of the software without the child stories, who knows what they would
end up with, and it might compromise the intent of what the customer wants, or even possibly deliver
something she doesn't want at all!
The final piece of the user story puzzle is to make sure there are acceptance criteria for every user
story that has been developed. This is not always an easy task, but is essential to making sure that the
user story is testable
so that it can be verified. The code must
operate properly so that the user story [as a requirement] can be shown to provide what the customer is
expecting in terms of usability, operation, and business value. It is also important to remember that you
may end up with multiple acceptance criteria for a single user story. This might be due
to the alternate outcomes of the user story, or it might just be that there need to be multiple tests for
a single story.
Let's take apart one of the child user stories we just developed and see how to add criteria.
|
|
Note several things about these criteria. First, we have to define the length and the parameters for a
saved location name. Further, we also need to ensure that the criteria definitions are acceptable to
the database or other downstream
This situation raises yet another consideration: error handling. Errors must be dealt
with in a graceful
manner so that the application won't crash. This means anticipating
the typical types of errors that a user might make, so that the application can make the appropriate
actions and not fail. We need to build in fault tolerance. And since we need to put
that into the application, it becomes another user story which will have its own criteria!
As a business traveler, I want to be alerted if weather is likely to delay my flight so that I can make appropriate changes to my travel arrangements.
MIDTERM EXAM IN TWO WEEKS, WEEK SEVEN!!