It’s difficult to understate the importance of requirements, and as a corollary, the importance of good requirements. While there are a great many arguments that can be made involving quality, continuous improvement, and other excellent and lofty ideals, the reason that most people will grasp immediately is cost.
According to a 2008 study by IAG Consulting, as reported in Network World, poor requirements can more than double the cost of a project, as a result of scope creep and inexpert engineering. Furthermore, the projects studied also delivered less functionality than originally desired and experienced considerable schedule delays in 50% of the projects studied.
Another contributing factor is rework caused by bad requirements, which can consume a significant percentage of a project’s resources and attendant budget. Generally speaking, the cost of fixing a defect increases exponentially in each subsequent stage of the software development lifecycle.
Another important outcome of good requirements engineering is communication. An approved, validated, and documented set of requirements means that everyone is working from the same set of information, which saves the time, effort, and frustration engendered by incomplete or vague communication.
It is therefore reasonable to say that investing more effort in the requirements phase of a project would likely result in better requirements, leading to better design specifications, more efficient testing, and lower post-release and support costs. The question then becomes how do you improve your requirements, assuming that adequate time and effort has been allocated? Rather than produce a pale imitation of much better works on the subject, I will provide you with opportunity to learn from others’ mistakes.
Thirteen Things You Should Never Do
1. Fail to understand the difference between a business rule, a process step, and a requirement.
By way of examples…
- A business rule is that in the United States, personal income tax returns are due on April 15th.
- A process step is gathering documentation required to file a personal income tax return, such as W2s and information pertaining to deductions.
- A requirement is that a personal income tax application shall allow entry of every piece of information on a W2 form that is required to complete the income tax return:
- Social Security number
- Employer identification number
- Wages, tips, other compensation
- Federal income tax withheld
- And so on
Ideally, software is built to comply with business rules. However, there are business rules that can’t be enforced by software, and software can’t change the business rules. In the example above, TurboTax can’t force anyone to file a tax return by April 15th. It can only remind you that it needs to be done…or that it’s late.
Process maps and use cases are both great ways of documenting the processes that generate the requirements. Additional thought is required though; you can’t just copy and paste process steps into a new document to produce a requirement. It’s likely that at least a few steps in the process will be outside the scope of the system, or out of the system’s control. Again referring to the example above, an income tax program is not going to be able to collect and organize paper documentation for you.
2. Fail to understand the difference between a system limitation in the current application and a requirement.
Most systems and processes have workarounds that have developed because the current system doesn’t exactly meet the needs of the process. Process engineering is outside the scope of this discussion, but it is important to keep in mind that just because something has “always been done this way” doesn’t mean that it always has to be done that way. If the answer to the question “Why has it always been done this way?” starts out with some variation on “The system won’t let us do—,” then you’re looking at a system limitation rather than a requirement. The mere fact that the old system won’t do X doesn’t dictate that the new system can’t do X.
3. Fail to consider whether or not a requirement is verifiable.
A good requirement is a statement that can be verified objectively. There is more than one way to verify that a requirement has been met:
- Test—Transaction execution with specific inputs and verifiable outputs. Each requirement must be verified by at least one test case. Some requirements may require more than one test case. However, if you find that you are writing many test cases for each requirement (ten or more), this can be a sign that the individual requirements are undesirably complex. In this case, you would consider simplifying the text of each requirement and increasing the number of requirements. On the flip side, if you can’t think of test cases to verify whether each requirement was properly implemented, your requirements are probably not sufficiently well defined.
- Inspection—Review of system attributes. This is usually done in the earlier stages of development, by programmers. In an ideal world, this includes peer reviews and code walkthroughs at the development, unit testing, and integration testing stages.
- Demonstration—Execution of system functions. There’s nothing wrong with demonstration methods such as visual verification. There are plenty of ways to document functionality using screenshots, outputs, and so on. Very occasionally, there are situations in which it is impossible to verify system functionality any other way. In my personal experience, this has usually involved voice recognition (IVR) interfaces.
If you cannot test a requirement, you cannot prove that your system meets requirements. That means your system can’t be validated. That’s not a situation you want to be in by the time you’re ready to start writing (or worse, executing) tests.
4. Use inconsistent and unclear wording and terminology.
If nobody knows what your requirements mean, you’re going to spend a lot of time explaining it after the requirements are written…if you’re lucky. If you’re not lucky, someone is going to guess what you meant and proceed accordingly. Think about whether you want to rely on whether or not a developer is a good guesser.
I thought not.
My own opinion is that no requirements document is complete without a listing of all industry- and site-specific terms, and a definition of all acronyms used in the document. If at all possible, avoid giving acronyms double-duty, such as using “ISP” for both “Internet Service Provider” and “Internal Service Process.” If you can’t avoid it, then don’t use the acronym. Spell out what you want, or someone will have to guess.
Clear, consistent language also cuts down on ambiguity. You’ve encountered ambiguity if a requirement statement can have several different meanings and you’re not sure which meaning is correct. A more insidious form of ambiguity results when multiple readers interpret the same requirement in different ways.
5. Use subjective words like “easy,” “fast,” and “user-friendly.”
There are four categories of words that have no place in requirements: the vague, the subjective, the moving target, and the lazy shorthand. Please note that upon further contemplation, some of these may fall into more than one category. Consider the possible difficulties that could result from using a combination of any of these unsuitable descriptors and buzzwords.
- The Vague – In my experience, vaguely worded requirements are the result of insufficient understanding of the user’s needs. “Should,” “may,” and similar words imply a level of uncertainty that has no place in a valid requirement. Do or do not; there is no “should.” Another problem that results from vague requirements is scope creep. Avoid using “includes,” “not limited to,” “etc.,” and “ad hoc” in your requirements; instead, take the time to define exactly what does and does not need to be included. The un-testable combination of “and/or” should never appear in a requirement. Choose one, and remember that “and” implies both, while “or” implies either. Also, “and/or” implies that “both” and “either” are equally acceptable. If you do not define which one you want, someone else will make the choice later in the development lifecycle, possibly without asking you, and you may not be happy with the decision. Requirements that include the word “support” are not specific enough to be testable. Instead, define in detail what the software must do to “support” a process.
- The Subjective – Easy, fast, and user-friendly are all highly desirable characteristics. They are also highly subjective terms. Is my perception of easy the same as yours? How can you prove that something is easy? For most users, the ease of using the system is almost entirely dependent upon the user interface design. Therefore, if you want your system to be easy to use, write your requirements in such a way that they include a set of standards for user interface design. Then, leave the details in the hands of the developers, because part of their job is to understand good user interface design. Jakob Nielsen’s short paper, Ten Usability Heuristics, provides an excellent platform-neutral, industry-neutral, audience-neutral guide. How fast is fast? Before you answer that question with “faster than the old system,” think about whether or not you want to take up your testers’ and system administrators’ time clocking the old system and the new one, in order to ensure that the requirement is met at the particular point in time that the test is run. Bear in mind that as servers are filled up, swapped out, and virtualized, the system’s performance characteristics will change. System and network administrators are the experts when it comes to tuning and maintenance, so why wouldn’t you give them the room to maneuver that they need to optimize system performance. Besides, given the pace of improvement in hardware and the continuous development of programming languages, it’s likely that your new system is going to be faster than your old system anyway. User-friendly for whom? If your user population includes both teenagers and retirees, making the system user-friendly for both groups will be a significant challenge. Even if you have a narrowly-defined user population, every system will have power users and not-so-powerful users. And when you get down to it, “user-friendly” ends up being the same as “easy”. See above.
- The Moving Target – My least-favorite word in this category, “state-of-the-art,” provides a moving target for your developers, and at some point, they will have to stop developing while the target keeps moving. In fact, because the state of the art is always changing, the system is never going to be able to catch up, and this requirement will never met…which means that it will be impossible for the system to be in a validated state. Another consideration is that there is plenty of good technology that’s not state-of-the-art, but is perfectly adequate for the job. Why mow a ten-foot by ten-foot patch of grass with a riding mower?
- The Lazy Shorthand – “Usually,” “ordinarily,” and “mostly” are all lazy shorthand for describing a default path. Investing some time in a robust set of process maps or use cases should help you define both normal and alternate paths, and provide precision in requirements.
6. Bring your old problems into your new software.
The most egregious example of this I’ve personally witnessed occurred in the attempt to completely replace a decades-old mainframe system with a web application. The old system contained three key sets of information, and not only were none of the sets of indexed or cross-referenced with each other, there was no way to connect them. As a result, the organization used the transaction number as a tracking and indexing number. Over time, more and more intelligence had been built into the transaction/tracking/index number, by which I mean instead of a simple sequence number, information such as the date, geographic locator codes, and so on, had been tacked on to the sequence number. This workaround was omnipresent, and had been for long enough that nobody could imagine a system without it. As a result, the organization insisted that the same intelligence (and maybe a few new items) had to be built into the primary key of every relational database table. I’m not a developer, but even I can see the inherent problem of taking a number that is supposed to do only one job and loading it up with three or four jobs. The old problem that was carried over resulted in a very serious new problem, which was that the required design was contrary to one of the first principles of building a relational database.
Furthermore, bringing old problems into your new system also brings the temptation to dictate design in your requirements. See number 10 below for more on that topic.
7. Fail to get feedback and signature approval on your requirements from all key personnel.
Requirements define the eventual product that will be delivered, and requiring input, review, and approval from key personnel is absolutely critical from a business standpoint.
- Input – The worst time to discover that your key personnel haven’t had any input on the requirements is the first time that you show them the new software. There are varying degrees of bad depending on whether that first time is in user acceptance testing, training, or after deployment. Key personnel are key because they are the ones who are going to have to live with the result of the system development effort. They are also the people who are going to be able to tell you whether or not the software meets the business’s needs.
- Review – The review process provides the earliest and least expensive opportunity to find and address problems, gaps, and inconsistencies in the requirements. It’s entirely possible as well that the review process will reveal conflicting needs among various user groups. Changing words in a document is a lot faster, easier, and cheaper than reworking code. By the end of the review period, key personnel should have reached consensus on the requirements set.
- Approval – Approval in this case means agreeing to the document as written, usually with a formal signature process. Approved requirements clearly document what has and has not been agreed to, reducing the possibility of mismatched expectations and the possibility of a contract dispute. A clean, clear set of approved requirements is an important communication tool that will be heavily utilized during the rest of the project, as well as after system deployment.
8. Make lots of assumptions, especially assumptions that others understand your processes as well as you do.
The only valid assumption that you can make when writing requirements is that during the course of the project, at least one person is going to have absolutely no idea what the business need is, or what is important to the users, or exactly what the software is really supposed to do. That is the person you are writing for.
9. Ignore the comments and recommendations from your quality representative.
Your quality representative’s job is make your requirements both compliant and better. Compliant is fairly straightforward; most industries are regulated by some agency or another, and the quality group’s area of expertise is making sure that your software is compliant.
Better can mean a lot of things, but a common mnemonic is “SMART”, which stands for:
- Specific – Requirements have a clearly specified objective, both individually and as a whole.
- Measurable – Requirements are defined in such a way that you can measure objectively whether or not the specified objective has been met.
- Achievable – Requirements are within the scope of what is attainable. If it’s not possible, don’t require it.
- Realistic – Requirements are within the scope of what is possible given all project constraints, not the least of which are time and budget.
- Testable – Requirements can be tested in a manner such that test results prove that the system meets the requirements’ specified objectives.
Quality is the group that is tasked with examining the requirements from a perspective that is different from the business users and IT. Day-to-day functionality is outside of quality representative’s scope, giving that person the ability to look at the forest rather than the trees.
10. Dictate design in your requirements.
Design information in requirements is no more desirable than mayonnaise in peanut butter.
Requirement text focuses on what the system does, rather than how the system does it. In the briefest possible terms, “what” is a requirement; “how” is a design element.
A good way to stay focused on What rather than How is to document a separate requirement for each standard transaction, form, or report. If you have difficulty separating a small group of transactions from each other (2 to 5 transactions), then the requirement can be written to encompass all of those transactions, but if it’s possible to split them out, that is preferable. If you have difficulty separating more than 5 transactions, it’s an early indicator that you probably need more information before you can write a good requirement.
Often, the source of design information in requirements is a desire to either replicate desirable functionality or avoid undesirable functionality in the current system. In other words, it’s lazy shorthand. An example of this I’ve seen is “New System shall have all the fields in Table A of the Old System.” This makes testing very difficult, as it requires someone sufficiently familiar with the code of both systems to sit down and review the entirety of New System to find the fields in Table A of Old System. It’s possible, but it’s not a good use of anyone’s time.
11. Change your requirements frequently during the project.
Every change to a requirement increases the cost necessary to meet that requirement.
Every change to a requirement increases the time necessary to meet that requirement.
Every change to a requirement increases the amount of work necessary to meet that requirement, for everyone downstream from the change.
Furthermore, frequent post-approval changes in requirements generate extra work both in quality and contractually, by way of the change management process. Naturally, this translates into further increases in cost and time, unless you don’t have a change management process…in which case you have bigger problems.
Even if your only change to the requirements is to remove some from the set, time, money, and effort have already been expended on those requirements, no matter when you drop them. The only difference is the amount of time, money, and effort that have been used developing requirements that are no longer in scope.
12. Think about the past instead of the future when you write your requirements.
Change is scary. This is why most people tend to think of new software as a better, faster, easier (note the use of subjective terms here) version of their current process, whether that process is manual or automated. They’re more interested in fixing the problems with their current functions and processes than rebuilding from the ground up. While it’s desirable—indeed, often necessary—to think about improving the current situation, it’s important not to lose sight of opportunities afforded by a new version or product. Maybe there’s finally a way to integrate a manual process, remove unused functionality, streamline processes, or eliminate a workaround.
13. Think that the new software is the answer to all your problems.
There are some problems that your software is not going to solve, and I’m not talking about barriers to world peace or smooth functioning of the air travel industry. Your problems may be related to training, processes, or the sheer unpredictability of user behavior. Software, specifically user interfaces, can be engineered to mitigate some of these problems. However, if the root cause of the problem is outside the software, then it’s entirely possible that the solution is, too.