Elements of Requirements Style, Part 2
This is the second in a series of four articles on writing high-quality requirements. The first article in the series discussed the use of the keyword “shall” when writing requirements and offered frameworks for writing functional requirements from the perspective of either the system or the user.
Parent and Child Requirements
When writing requirements in a hierarchical fashion, the BA records a parent requirement and one or more child requirements. The parent requirement is satisfied by implementing all of its children. Here’s an illustration of a hierarchical requirement with some problems:
3.4 The requester shall enter a charge number for each chemical ordered.
3.4.1 The system shall validate charge numbers against the master corporate charge number list. If the charge number is invalid, the system shall notify the requester and shall not accept the order.
3.4.2 The charge number entered shall apply to an entire order, not to individual line items in the order.
Notice that this parent requirement, 3.4, is written in the form of a functional requirement. It’s not entirely clear how many requirements are represented here: two or three? Also notice that there is a conflict between the parent requirement and one of its child requirements, 3.4.2. If each ordered chemical is a line item, exactly how many charge numbers is the requester supposed to enter?
These sorts of problems disappear if the parent requirement is written in the form of a heading or title instead of in the form of a functional requirement. Consider using this style whenever you have a set of child requirements that, in the aggregate, constitute a parent requirement. Following is an improved version of the preceding example:
3.4 Charge Numbers
3.4.1 The requester shall enter a charge number for each chemical in an order.
3.4.2 The system shall validate charge numbers against the master corporate charge number list. If the charge number is not found on this list, the system shall notify the requester and shall not accept the order.
What Was That Again?
Ambiguity is the great bugaboo of software requirements. Ambiguity shows up in two forms. One form I can catch myself. I read a requirement and realize that I can interpret it in more than one way. I don’t know which interpretation is correct, but at least I caught the ambiguity.
The other type of ambiguity is much harder to spot. Suppose the BA gives the requirements specification to several reviewers. The reviewers encounter an ambiguous requirement that makes sense to each of them but means something different to each of them. The reviewers all report back, “These requirements are fine.” They didn’t find the ambiguity because each reviewer knows only his own interpretation of that requirement. Let’s see some sources of ambiguity to watch for and some suggestions about how to write less ambiguous requirements.
Complex Boolean logic offers many opportunities for ambiguities and missing requirements. Consider the following paragraph:
If an order is placed for a chemical to a vendor, the system shall check to see if there are any other pending orders for that chemical. If there are, the system shall display the vendor name, vendor catalog number, and the name of the person who placed each previous order. If the user wishes to contact any person who placed a previous order, the system shall allow the user to send that person an e-mail message.
This long requirement is difficult to read and contains multiple functionality descriptions that should be split into separate requirements. Plus, it has some gaps. Writing requirements in this style makes it difficult to see whether the outcomes of all the if/then branches are specified. “Else” conditions are often overlooked with this sort of textual representation. Nested “or”, “and”, and “not” clauses are better represented using a decision table or decision tree.
A decision tree such as that shown in Figure 1 would immediately reveal that the system’s behavior is not specified if there are no pending orders for that particular chemical. Other false outcomes from the decisions are also unspecified. Implicitly, perhaps the reader will conclude that the system should do nothing if the various “if” conditions described here are false, but that’s an assumption forced by the incompleteness.
Figure 1. Sample decision tree for complex logic.
Expressions involving compound operators—such as “IF this AND (that OR the other)”—are even more confusing:
If the amount of the cash refund is less than $50 or the amount of the cash refund is $50 or greater and the current user is a supervisor, then the system shall open the cash register drawer.
Making this requirement understandable and unambiguous requires either parentheses (awkward) or splitting into multiple requirements (better).
Negative (or inverse) requirements are another source of confusion. Try to recast inverse requirements in a positive sense, to state what the system will do under certain circumstances. Table 1 states several functional requirements, all drawn from actual projects, that contain negation, along with possible ways to rewrite them in a positive sense. I’ve also restated these passive-voice requirements into the less ambiguous active voice, which clearly shows what entity is taking each action. Note that changing a negative requirement into a positive one often requires inserting the word only to identify the conditions that permit the system action being described to take place. In the third example, note also the ambiguity between cannot (as in “not able to”) and may not (as in “not permitted to”).
Table 1. Removing Negation from Functional Requirements
Avoid double and triple negatives in all circumstances. Consider this example:
Training rewards and points will not be visible to users who cannot participate in training rewards.
We can rephrase this double negative into a positive statement that’s easier to understand:
The system shall display training rewards and points only to users who are permitted to participate in training rewards.
Following is another illustration of recasting a double negative into a positive using an “only” constraint. The original requirement said:
Users who are delivered service without being authenticated should not generate accounting records.
Let’s state it as a positive action that the developer can actually implement:
The system shall generate accounting records only for users who are delivered service after being authenticated.
Multiple negations can lead to ambiguous requirements, as illustrated here:
Records, however, should not fail validation if these attributes are not present at all.
Does this mean that the records should fail validation if the attributes are present? Probably not. The context might make the meaning of this requirement clearer, but as it’s written, it raises a question in my mind.
The main message here is to think positive when writing requirements!
Don’t forget to leave your comments below.