Writing Requirements

This article captures the art of software requirements writing as it’s done at Divergent Labs.

The requirements document lists everything the product or feature will do, in a way that everyone on a team can read. Let’s start with a few examples from a hypothetical project that allows a user to enter comments attached to specific frames in a video. These requirements are in no particular order for this example.

  • The video frame will not be resizable separately from the whole window; it will always occupy 3/5 the window width, and the height will depend on the video aspect ratio.
  • The following data points will show at all times next to the video frame: Timecode, Project title, User ID.
  • When a comment is being edited, the user can either set the comment’s timecode based on the current video position, or enter it manually.
  • The user needs to be able to customize which columns show in the data grid.
  • For each comment, the system will store the video file, commenter, timecode, comment type, and comment text
  • The administrator may set up a default value for the comment type.
  • Must be frame accurate.
  • Must allow exporting individual frames in JPG or PNG format only.

The main thing to notice first is that the requirements are quite specific and unambiguous, yet they are wide open to any technical and user-interface design.

  • Specific – The requirements above list exactly which formats can be exported, which data points show on screen, and how new entries get default values. The user will not be able to export in GIF format or see the video file name. All the “Whats” are decided.
  • Open – The requirements do not say anything how the user will customize the data grid, how they will export a frame image, or by what means the server data will be accessed. None of the “Hows” are addressed.

So, requirements are not just a “general idea” of where the project will go, but rather an exact list of things it will and will not do (all the Whats), while carefully omitting any ideas on how it will work (none of the Hows). It’s both specific and open.

The document

The requirements document should be organized under general headings based on the project scope. Some of the usual headings are:

  • Purpose – A single sentence stating the ultimate purpose of the project (important!)
  • Data Requirements – Might list the data points captured, or those that must appear on reports or must be sent to another system
  • User Interface Requirements – Might list use cases or specific points about ease of use
  • Technical Requirements – Might list compatibility points, scaling, or latency
  • Security Requirements – Might list points about user classes and which data points need to be protected in what ways

The document should be approved before the core engineering phases begin, and gets used for three main things:

  1. As the basis for building the architecture and technical design.
  2. As the master document for validating that the technical design is complete.
  3. As a basis for testing – ensuring that the built product meets the requirements.

How do you draft it?

When drafting, mainly, you listen to people and take notes, then extract what they’ve said into “requirements language”. Listen in particular to use cases and why a new product is needed over the prior way of doing things.

The customer might say this regarding the video commenting project: “We need to make it easier for users to rate the video quality and find flaws. Today, they have to manually type the timecodes in Word, and there’s a lot of typos. Also they don’t always put the category down, and then someone else has to collate all that information. The new system will automate some of the steps and improve accuracy. They’ll just hit Play and then as soon as they start typing, it will stop and copy the still image into the editor, then they can drag an arrow or circle from a toolbar and literally point to the problem area in the picture. Then they just hit Enter and it starts playing again.”

The example above provides a lot of information about use cases, and it envisions a specific design. To get from this vision to bulleted items in requirements language, we need to separate statements about purpose and design ideas from those that are true requirements. It’s not necessarily going to be in the end design that pressing Enter starts the playback, because maybe it will need to allow multiple paragraph comments, and getting into that is a design problem anyway, not a requirements problem. So instead we extract and generalize the requirement based on what we know about the use case and purpose:

  • 100% accuracy rate on timecode entry.
  • Starting and pausing playback needs to be extremely convenient using keyboard control.

Similarly, we want to exclude the specifics about the toolbar and dragging (which are design points) and figure out what the real need is. Maybe the customer doesn’t need arbitrary graphic manipulation, but rather something like this:

  • Each comment refers to a single target point in the frame, which the user designates.

Limiting the requirement like that (resisting the temptation to do design now) opens the door to a variety of other ways to specify the target point, which might actually be faster and clearer than the originally conceived way of dragging an arrow icon from a tool bar.

By listening and extracting in this manner, you eventually build up a number of headings and bulleted points, all written in plain language that non-technical people can read.

Completing it

If a requirements drafter interviews multiple people, it frequently exposes incompatible ideas or disagreements, which then have to be resolved. I might write something like this in an early draft:

  • Allow exporting a video frame as a still graphic to a file or to the clipboard [Alice says we don’t need this. Bob:What’s the use case?]

Then a conversation ensues with Bob, who requested the feature, and he explains that we need to convert it to JPG so we can overlay the arrow icon on it, but he didn’t mean to imply that the resulting file should be saved outside the system. In thinking it through that way, Bob was doing design, and that might be a good way to achieve the functionality, but there are other ways as well, and the discussion of how to identify the target spot in the frame is not about requirements. So in this example, the idea and the whole bullet point just gets deleted. When design ideas get brought up like this, you can make a note of it for the design phase, but leave it out for now.

Often the first draft also reveals the holes, or the “laters” – things that some team members were hoping to figure out “later”. But for an efficient software development process, there is no later. So if there are some incomplete ideas floated such as “We might need to email the viewer when the videos are ready to comment on”, then now is the time to figure out things like, when is a video “ready”? Is there a list of viewers separate for each video?

As all that gets pinned down, we make more drafts of the requirements document, and eventually get a written final approval of it. This approval is the most important milestone in the software life cycle.

Why is it important?

A lot of software development happens without formal requirements like this, so why is it so important? In my experience, these are the reasons:

  • It is the best way to achieve team agreement on the project. It forces the question of what is and is not going to be included, and puts to rest any attempts to derail the project with new ideas. Anything that isn’t in the requirements is not in the project for this version. (Those things can become a new project.)
  • It opens creativity. The technical design section below explains why.
  • Requirements, technical design, and documentation save time. Without documents on the hard milestones in an accessible archive, simple questions turn into big reverse-engineering projects or may involve discussions and phone calls to try to recall history about why decisions were made. That’s expensive.
  • It makes development fast. When you know exactly what you are trying to achieve, you can make a straight line to the end of the project. I’ve been called “fast” but really I just go at a normal speed in a straighter line than some other people. It is nearly impossible to estimate effort or complete a project “on time” unless it is bound by well written requirements.

Using requirements to draft a technical design

In addition to being called fast, I have also been called enormously “creative”, but really I am just rigorous about requirements. Once the bullet points are all there in true requirements language, I have no constraints on design, so I can find the very best way to do things.

Consider the video commenting project from above, specifically the design for marking the point on the frame where the comment refers. The requirements process helps us throw out all the misunderstandings, non-requirements, and assumed design points, and we are left with simplicity, which is easier to design with. I might make a design choice in which a single click on the video, while it is playing, stops the playback and simultaneously identifies that point as the target point for a new comment. This achieves 100% accuracy in the timecode and achieves all the other requirements I’ve been using as examples, and does it with one click. In retrospect, users will say “Of course it works that way, it’s only natural”, but in the early requirements process, there might have been many other more complicated ideas about it. It takes engineering rigor to make something appear “natural”.

As a final note, it should be stressed that specifications or detailed technical designs are not just a more detailed version of requirements. They are written for engineers and describe properties of the software system. The requirements say “What” while the design says “How”. Both the requirements and technical design continue to be important (and very different) documents, for the duration of the project.