Rather than expecting use cases to contain one hundred percent of the system’s functionality, I prefer to employ use cases to help the business analyst discover the functional requirements. That is, the use cases become a tool to reveal functionality rather than being an end requirements deliverable themselves. Users can review the use cases to validate whether a system that implemented the use cases would meet their needs. The BA can study each use case and derive the functional requirements the developer must implement to realize the use case in software. I like to store those functional requirements in a traditional SRS, although you could add them to the use case description if you prefer.
I’m often asked, “Which comes first: use cases or functional requirements?” The answer is use cases. Use cases represent requirements at a higher level of abstraction than do the detailed functional requirements. I like to focus initially on understanding the user’s goals so that we can see how they might use the product to achieve those goals. From that information, the BA can derive the necessary functionality that must be implemented so that the users can perform those use cases and achieve their goals. Conversely, if users present fragments of functionality during a requirements elicitation discussion, the BA should try to figure out which use case that functionality might with, if any.
Functional requirements—or hints about them—lurk in various parts of the use case. The remainder of this article describes a thought process a BA can go through to identify the less obvious functional requirements from the elements of a use case description.
Preconditions
Preconditions state conditions that must be true before the actor can perform the use case. The system must test whether each precondition is true. However, use case descriptions rarely state what the system should do if a precondition is not satisfied. The analyst needs to determine how best to handle these situations.
Suppose a precondition for one use case states, “The patron’s account must be set up for payroll deduction.” How does the system behave if the patron attempts to perform this use case but his account is not yet set up for payroll deduction? Should the system just notify the patron that he can’t proceed? Or should the system perhaps give the patron the opportunity to register for payroll deduction and then proceed with the use case? Someone has to answer these questions and the SRS is the place to provide the answers.
Postconditions
Postconditions describe outcomes that are true at the successful conclusion of the use case. The steps in the normal flow naturally lead to certain postconditions that indicate the user’s goal has been achieved. Other conditions, however, might not be visible to the user and therefore might not become a part of a user-centric use case description.
Consider an automated teller machine. After a cash withdrawal, the ATM software needs to update its record of the amount of cash remaining in the machine by subtracting the amount withdrawn. Perhaps if the cash remaining drops below a predetermined threshold the system is supposed to notify someone in the bank to reload the machine with additional money. I doubt any user will ever convey this information during a discussion of user requirements, yet the developer needs to know about this functionality.
How can you best communicate this knowledge to the developers and testers? There are two options. One is to leave the use case at the higher level of abstraction that represents the user’s view and have the requirements analyst derive the additional requirements through analysis. The BA can place those requirements in an SRS that is organized to best meet the developer’s needs. The second alternative is for the BA to include those additional details directly in the use case description. That behind-the-scenes information is not part of the user’s view of the system as a black box. Instead, you can think of that information as being white-box details about the internal workings of the use case that the analyst must convey to the developer.
Normal and Alternative Flows
The functionality needed to carry out the dialog between the actor and the system is usually straightforward. Simply reiterating these steps in the form of functional requirements doesn’t add knowledge, although it might help organize the information more usefully for the developer. The BA needs to look carefully at the normal flow and alternative flows to see if there’s any additional functionality that isn’t explicitly stated in the use case description. For example, under what conditions should the system offer the user the option to branch down an alternative flow path? Also, does the system need to do anything to reset itself so that it’s ready for the next transaction after the normal flow or an alternative flow is fully executed?
Exceptions
The BA needs to determine how the system could detect each exception and what it should do in each case. A recovery option might exist, such as asking the user to correct an erroneous data entry. If recovery isn’t possible, the system might need to restore itself to the state that existed prior to beginning the use case. The BA needs to identify the functionality associated with such recovery and restore activities and communicate that information to the developer.
Business Rules
Many use cases are influenced by business rules. The use case description should indicate which business rules pertain. It’s up to the BA to determine exactly what functionality the developer must implement to comply with each rule or to enforce it. These derived functional requirements should be recorded somewhere (I recommend documenting them in the SRS), rather than just expecting every developer to figure out the right way to comply with the pertinent business rules.
Special Requirements and Assumptions
The use case might assume that, for instance, the product’s connection to the Internet is working. But what if it’s not? The developer must implement some functionality to test for this error condition and handle it in an appropriate way.
In my experience, the process of having the BA examine a use case in this fashion to derive pertinent functional requirements adds considerable value to the requirements development process. There’s always more functionality hinted at in the use case than is obvious from simply reading it. Someone needs to discern this latent functionality. I would prefer to have an experienced BA do it rather than a developer.
Use Cases: A Pragmatic Approach
I recently spoke to a developer who said it was much more helpful to receive requirements information organized in a structured way from the BA than to have to figure out those details on his own. This developer preferred to rely on the BA’s greater experience with understanding the problem domain and deriving the pertinent functional requirements. Not only did this result in better requirements, but it also allowed the developer to focus his talents and energy where he added the most value, in designing and coding the software.
My philosophy of employing use cases as a tool to help me discover functional requirements means that I don’t feel a need to force every bit of functionality into a use case. It also gives me the option of writing use cases at whatever level of detail is appropriate. I might write some use cases in considerable detail to elaborate all their alternative flows, exceptions, and special requirements. I could leave other use cases at a high level, containing just enough information for me to deduce the pertinent functional requirements on my own. The functional requirements are the end result of requirements analysis, regardless of where you choose to store them or whether you even write them down at all. Developers don’t implement use cases: they implement specific fragments of functional behavior that allow users to accomplish valuable tasks with the software.
Deriving functional requirements from the use case always takes place on the journey from ideas to executable software. The question is simply a matter of who you want to have doing that derivation and when. If you deliver only use cases without all the functional detail to developers, each developer must derive the additional functionality on his own. It’s also unlikely that all developers will record the functional requirements they identify. This makes it hard for testers to know exactly what they need to test. It also increases the chance that someone will inadvertently fail to implement certain necessary functionality. If you’re outsourcing construction of the software, you can’t expect the vendor’s developers to accurately determine the unstated functionality from a use case description.
You will almost always have additional functional requirements that do not fit nicely into a particular use case. Earlier in this article, I mentioned the example of logging in to a system. Clearly, that functionality must be implemented, but I don’t consider it to be a use case. You might also have functional requirements that span multiple use cases. Consider the behavior the system should exhibit if a required Internet connection goes down. The Internet connection could fail while the user is executing any use case. Therefore, this error condition doesn’t constitute an exception flow associated with a specific use case. It needs to be detected and handled in multiple operations. The BA can place all the functional requirements that are not associated with or derived from a particular use case into the logically appropriate section of the SRS.
I have found use cases to be a highly valuable technique for exploring requirements on many types of projects. But I also value the structured SRS as an effective place to adequately document the functional requirements. Keep in mind that these documents are simply containers for different types of requirements information. You can just as readily store use cases, functional requirements, and other types of requirements information in the database of a requirements management tool or in other forms. Just don’t expect use cases to replace all your other strategies for discovering and documenting software requirements.
Read When Use Cases Aren’t Enough, Part 1.
Read When Use Cases Aren’t Enough, Part 2.
Jama Software has partnered with Karl Wiegers to share licensed content from his books and articles on our web site via a series of blog posts, whitepapers and webinars. Karl Wiegers is an independent consultant and not an employee of Jama. He can be reached at http://www.processimpact.com. Enjoy these free requirements management resources.