Requirements Engineering¶
Based on Chp 4 of Sommerville “Software Engineering” (9th edition)
Introduction¶
requirements are about what a system should do
requirements are not about how a system should be implemented (that’s design and implementation)
the activities of figuring out what users want, how they translate into software, and documenting all this is known as requirements engineering
requirements can be high-level and abstract, or low-level and detailed
Categories of Requirements¶
the different kinds of requirements can be organized into various categories
for example, one basic organization is:
- user requirements are what the user wants, and are typically informal and high-level (so that users can easily help create/understand them)
- system requirements are exact, detailed descriptions of what the system should do, and are specified with more detail than user requirements
keep in mind who will be reading the requirements, and write them for those readers
(Figure 4.1 from Sommerville 9)
Functional and Non-functional Requirements¶
another basic distinction is functional vs non-functional requirements
functional requirements are about how a system should function, i.e. how it should (or should not!) react to a given input
non-functional requirements are constraints on the services and functions of the system, and are often system-wide
- the best way to understand non-functional requirements is to look at the examples in the diagram below
Functional and Non-functional Requirements¶
for example, suppose you are creating a new course-management system for a school
functional requirements for such a system might include:
- students can see a list all the courses they have taken and are currently enrolled in
- every day, a list of students currently enrolled in a course will be available to the teacher of the course
- teachers (but not students) can post announcements to their classes
- anyone in a class can start, or participate, in a discussion
- class should be able to make in-class groups of students
on-functional requirements for such a system might include:
- all data must be stored on Canadian-owned computers
- all personal information about students (including marks) must be kept private and made available only to the individual student and teaching staff
- user IDs must be the same as school IDs, i.e. 9-digit numbers
- up to 20,000 individual students could be enrolled in courses at any one time, and each individual student needs at least 25MB of disk space for files and submissions
- old courses must remain usable for at least one year after the end date
- the system should be efficient and easy to use
please note that these requirements are vague and informal, and leave a lot of room for interpretation as to what they actually mean!
a lot of what makes requirements engineering hard is make clear what exactly is required
ideally, discussion with users is needed
- indeed, Agile methodologies insist upon consistent and frequent user interaction and feedback
but keep in mind just because a user thinks they want feature X, doesn’t really mean they want it!
- what the user thinks feature X means might be different than what the developer thinks it means
- or, after getting to use it, the user might discover that they really don’t need or want feature X after all
- other users have think “not X” is an important feature — so requirements can be inconsistent!
in practice, aim for requirements that:
- are precise and not open to interpretation
- can, if possible, be quantitatively tested, i.e. don’t say “the system should be fast”, say it in a way that can be measured, e.g. “the system should have a response 500ms for any user basic interaction”
- can be demonstrated to users to get their feedback
- address specific and actual (user) problems
- can be re-written as necessary during the project to make them clearer, more complete, more consistent, etc.
Requirements Document¶
in traditional non-Agile software engineering, requirements are summarized in a Requirements Document
this is the official list of requirements for the system
agile software engineering often doesn’t do this, believing instead that requirements change so frequently that such a document will almost always be out of date
- e.g. extreme programming (XP) writes requirements incrementally and keeps them on index cards that are easy to change
many projects still find it useful to clearly state important requirements
they are useful to users, developers, testers, managers
the textbook includes examples of the sections that might appear in a requirements document (4.2), e.g.
- preface (who is the document meant to be read by?)
- introduction (overall description of project, why it’s needed, how it fits with current systems, etc.)
- glossary (explanations of technical terms)
- user requirements
- system architecture (high-level organization of the system)
- system models (e.g. diagrams of important parts of the system)
- system evolution (discussion of maintenance and operating concerns after releases, e.g. how will the system be kept running, how will it be upgraded, how will bug fixes and new features be deployed, etc.)
- appendices (sections on other important topics, e.g. discussion of the database or security tools to be used)
Writing Requirements¶
requirements are notoriously difficult to write
- sometimes the actual requirements are unclear
- or finding the best words that everyone understands can be hard
- even seemingly simple requirements can have subtleties that can cause problems if not handled well
good requirements should be: clear, unambiguous, easy to understand, complete, and consistent
good requirements should generally not say how they should be implemented
here are some ways that you can write requirements …
Natural Language Requirements¶
ordinary English sentences written as clearly as possible
use numbering, bullet points, underlining, sections, etc. to help clarity
be careful about using technical terms: make sure you are certain readers know their meaning
- consider adding a glossary that defines technical terms
- web hyperlinks can be helpful here, i.e. have hyperlinks to the defintions of all the important terms
sometimes concrete examples can be included to help clarify the intended meaning of a requirement
- e.g. a sketch of a GUI widget might be a better way to describe the button then using a lot of text
(Figure 4.9 from Sommerville 9)
natural language tends to be relatively easy to write (everyone has had practice writing natural language), but hard to read (due to ambiguities)
Structured Natural Language¶
structured natural language requirements follow a template, like filling out a form for each requirement
depending upon the systems and type of requirements, different kinds of forms might be used
(Figure 4.10 from Sommerville 9)
Mathematical Specifications¶
precise mathematical specifications based on logic, set theory, algebra, etc.
in programming, the use of pre-conditions and post-conditions to specify the behaviour of a function is an example of a mathematical specification, e.g.:
// Pre-condition:
// v.size() > 0
// T is a type that supports <=
// Post-condition:
// returns x such that x in v, and for all y in v, x <= y;
// v is unchanged
T min(const vector<T>& v)
the pre and post conditions are written in semi-formal English, but it is possible to use a precisely defined logic for such things, and have another program check that they are correct and sensible
it’s instructive to compare this formal specification approach of the min function to the test-driven development (TDD) version
recall that TDD says that you ought to write tests first, and use those to help understand the function you are writing, e.g.:
min({}) == error min({2}) == 2 min({2,3,1}) == 1 min({2,2,2}) == 2
a nice thing about this approach is that it makes some of the important cases (like arrays with duplicate values) clear, and forces you to think about how to handle that case
- in contrast, the formal specification makes no special mention of this case
- however, it may not always be clear in TDD what test cases should be included, and how many cases are best
- in TDD, you might simply miss an important case because it didn’t occur to you
relatively hard to read and write: requires training in the relevant mathematics
some modern mathematical specification languages can be checked automatically by computer to ensure the specifications are consist
- can be extremely useful!
- but forces you to think clearly and avoid ambiguity
- takes time to learn, but can be interesting to use for developers since it’s similar to coding
- in practice, has proven useful in specifying concurrent/parallel systems, where reasoning about the behaviour of interacting processes can be extremely subtle and tricky
- for instance, here is an example of TLA+
note that universities often hold up mathematical specification as a model of a good way to write specifications
this seems to be because
- academic computer science is often very closely related to mathematics, e.g. the kinds of problems academics like to study tend to be mathematical
- academic problems are often relatively small and well-defined, and so amenable to mathematical description
real-life problems often seem more vague, messy, and ill-specified, and there is no obvious way to formalize them
plus the formalization of a real problem is often as difficult as writing the program itself
- how do you know the formalization is complete and consistent?
Graphical Notation¶
diagrams and charts are often useful supplements to written requirements
many, many different kinds of diagrams and charts!
the Unified Modeling language (UML) is one popular graphical notation that standardizes a number of popular graphical models
for example, class diagrams are popular for organizing classes in object-oriented programming languages
- in a class diagram, classes are boxes and arrows show inheritance (is-a) relationships
for example, entity-relationship diagrams in databases
for example, state diagrams represent the state of a system by nodes, and transitions by arrows
- regular expressions can be treated as state machines
we’ll see some popular kinds of charts later
Requirements Elicitation and Analysis¶
how do you determine the requirements for a system?
some requirements may be give to you
other requirements may need to be determined by analyzing the problem domain
- one interesting way to do this is by an ethnographic study, i.e.
discovering requirements by watching people doing real work
- for instance, if you were going to make software for a young child’s electronic toy, watching children play with the toy is probably a good idea
or interviewing future users and other stakeholders
- a feasibility study might consists of interviews and discussions with stakeholders
- interviews could be open-ended, or follow a pre-made script of questions
- interviews could be small, or large
- good interviewing is a skill that takes practice!
keep in mind that many stakeholders:
- don’t know for sure what they want
- use their own terminology that might differ from yours, or be too vague
- e.g. a manager might say “we want a recursive learning algorithm”, where “recursive” probably doesn’t mean a function that calls itself
- find it difficult to explain concepts they are deeply familiar with to
people who are not also deeply familiar with them
- can you explain how to ride a bike?
- many AI-type problems that humans have no problems solving can be difficult in part because no one has a clear, step-by-step way of describing how to solve those problems
- may have requirements that are inconsistent with the requirements of other stakeholders
- politics can be involved, e.g. people might try to get their requirements accepted as a way to improve their stature in the company
- could change their mind, or leave (e.g. get a new job, go on vacation, go on parental leave, …)
some systems might have many different stakeholders, e.g. consider a course-management system like Canvas:
- students
- instructors
- TAs
- non-teachers who want to use Canvas for one of its features, e.g. as a discussion group, or as a way to post learning materials for staff
- course designers
- system administrators (responsible for keeping the system running)
- guests, who want to explore the system or try it out without committing to a role
once you have the basic requirements, you should
- organize them
- prioritize them
- write clear specifications for them
Use Cases (Scenarios)¶
a good way to discover requirements is to have stakeholders discuss common usage scenarios
we’ll call these use cases, i.e. examples of uses
different methodologies have different terms for these, and may differ in the details of what exactly they are
but the key idea is the same: a use case describes a common usage scenario for a system
use cases are usually more concrete and easier to think about than abstract requirements
use cases are often easy to base on actual usage of similar software
Use Cases¶
use cases typically describe an interaction between users and the system
a good use case identifies the users by their role, and how they interact with the system
(Figure 4.15 from Sommerville 9)
Requirements Validation¶
how do you know your requirements are clear, complete, and consistent?
basically, review the requirements carefully with these things in mind!
get experts to help out if you can
- real users
- human editors can help with grammar, style, and clarity
another way to check requirements is to create a prototype
- a small, limited-function version of the system meant to check important requirements
- prototypes need to be completed more quickly than the final product, and so may use special prototyping tools
another way to check the quality of a requirement is to derive test cases from it
- all requirements should be testable! otherwise, how would you know if they’ve been met?
- if you can’t think of how you would test the requirement, it may be too vague or too big and so should be re-written
Managing Requirements¶
as you might guess, in a large project managing requirements is a non-trivial task
there are lots of them, they have to be written carefully, they can change, etc.
even basic questions like how should requirements be stored can become tricky in big projects
- in a database?
- in HTML or markdown (don’t forget that any images would in separate files)?
- would requirements files and folders have a standard format?
it takes time, money, and expertise to do all this well
you probably also want to save the things that worked well to re-use in future projects
so in big projects it pays to think carefully about how to manage requirements
- need to keep track of who changed a requirement, and why they changed it
- changing one requirement might have an impact on other parts of the system
- there maybe significant costs associated with a requirements change, e.g. changing the database might require buying a new database, or buying support tools
section 4.7 of Sommerville 9 gives some ideas for how requirements might be managed