Applied Software Project Management – Product Engineering Practices


This is part of the supporting material from our first book, Applied Software Project Management, which was published by O’Reilly in 2005. You can see all of the material here:

Software Requirements Specification

It seems obvious that we need to know what software is supposed to do before we build it. Nevertheless, many projects are delayed (or fail completely) because development begins before anyone on the project team really understands how the software should behave. The solution to this problem is to take the time to gather and verify the software requirements—documentation that completely describes the behavior that is required of the software—before the software is designed, built, and tested.

A software requirements specification (SRS) is a complete description of the behavior of the software to be developed. It includes a set of use cases that describe all of the interactions that the users will have with the software. In addition to use cases, the SRS contains functional requirements, which define the internal workings of the software: that is, the calculations, technical details, data manipulation and processing, and other specific functionality that shows how the use cases are to be satisfied. It also contains nonfunctional requirements, which impose constraints on the design or implementation (such as performance requirements, quality standards or design constraints).

SRS Outline

The following document contains the outline for a software requirements specification. It includes templates for use cases, functional requirements and nonfunctional requirements.

SRS Development Script

Like use cases, the SRS should be developed iteratively. The goal of the SRS Development Script is to remove as many defects as possible from the SRS. Many people have trouble figuring out what constitutes a defect. In this case, a defect is any planned software behavior which a project team member, user, stakeholder or decision-maker does not agree with. This means that defects could be caused by any number of problems:

  • Somebody does not believe that the planned behavior will satisfy the users’ or stakeholders’ needs
  • Somebody believes that those needs may be better satisfied with different behavior
  • An inspector does not understand what’s written, or feels that it is ambiguous or confusing
  • A project team member does not believe that the behavior can be implemented as written
  • Two or more requirements contradict each other—an implementation that satisfies one cannot satisfy the others

If there is a requirement in the SRS that has one of these problems, it must be identified and fixed so that everyone agrees on everything in the document. There will almost certainly be defects that slip through—no inspection team is perfect—and each of these will cost much more time to fix after they have been designed, coded and tested than it would have if it had been caught using the SRS development script. The goal is to find as many defects as possible, in order to reduce the amount of time that the team must spend later on in the project undoing the few that slipped past.

The following table contains the SRS development script:


Name Software Requirements Specification Development Script
Purpose To elicit software requirements, document them in a software requirements specification, and verify that it is correct.
 Summary The development of the software requirements specification should be the most iterative part of the entire project. This is the point where the behavior of the software to be developed is at its most malleable—it has only been described in words, and has not yet been realized in design, architecture, code, test plans or any other work product. The goal of this script is to ensure that as many defects are found as possible, because each defect missed at this stage will be much more costly to detect and fix later on in the project.
 Work Products Output
Software Requirements Specification (SRS)
Entry Criteria A requirements analyst has a vision and scope document for a project and has identified a set of users, stakeholders, and other people who will participate in the elicitation process.
Basic Course of Events
  1. Elicitation: The script begins with the elicitation process. The requirements analyst works with users, stakeholders, and other people to elicit their needs and any known requirements. If there are outstanding issues or SRS defects, the analyst resolves them during the elicitation activities.
  2. Documentation: The requirements analyst creates or updates the draft of the SRS to reflect the data elicited in step 1.
  3. Verification: A team of reviewers performs a review of the SRS draft. In the first iteration, a small number of reviewers perform a deskcheck of the draft. Later reviews will include more people, and may be inspections instead of deskchecks. Walkthroughs should be conducted for non-technical people who still need to understand the contents of the SRS. The last iteration must be an inspection.
Exit Criteria The script ends after the draft was inspected in step 3 and no defects were found. If defects were found or there was only a deskcheck performed in step 3 then the script returns to step 1 for the next iteration.

Use Cases

A use case is a description of a specific interaction that a user may have with the software. Use cases are deceptively simple tools for describing the behavior of the software. A use case contains a textual description of all of the ways that the intended users could work with the software through its interface. Use cases do not describe any internal workings of the software, nor do they explain how that software will be implemented. They simply show the steps that the user follows to use the software to do his work. All of the ways that the users interact with the software can be described in this manner.

Use Case Template

A typical use case includes these sections, usually laid out in a table:

Name Use case number and name
Summary Brief description of the use case
Rationale Description of the reason that the use case is needed
Users A list of all categories of users that interact with this use case
Preconditions The state of the software before the use case begins
Basic Course of Events A numbered list of interactions between the system and one or more users
Alternative Paths Conditions under which the basic course of events could change
Postconditions The state of the software after the use case ends

This example shows a final use case for a search-and-replace function (which is numbered UC-8):

Name UC-8: Search
Summary All occurrences of a search term are replaced with replacement text.
Rationale While editing a document, many users find that there is text somewhere in the file being edited that needs to be replaced, but searching for it manually by looking through the entire document is time-consuming and ineffective. The search-and-replace function allows the user to find it automatically and replace it with specified text. Sometimes this term is repeated in many places and needs to be replaced. At other times, only the first occurrence should be replaced. The user may also wish to simply find the location of that text without replacing it.
Users All users
Preconditions A document is loaded and being edited.
Basic Course of Events
  1. The user indicates that the software is to perform a search-and-replace in the document.
  2. The software responds by requesting the search term and the replacement text.
  3. The user inputs the search term and replacement text and indicates that all occurrences are to be replaced.
  4. The software replaces all occurrences of the search term with the replacement text.
Alternative Paths
  1. In Step 3, the user indicates that only the first occurrence is to be replaced. In this case, the software finds the first occurrence of the search term in the document being edited and replaces it with the replacement text. The postcondition state is identical, except only the first occurrence is replaced, and the replacement text is highlighted.
  2. In Step 3, the user indicates that the software is only to search and not replace, and does not specify replacement text. In this case, the software highlights the first occurrence of the search term and the use case ends.
  3. The user may decide to abort the search-and-replace operation at any time during Steps 1, 2, or 3. In this case, the software returns to the precondition state.
Postconditions All occurrences of the search term have been replaced with the replacement text.

Use Case Development Script

As the use cases are developed, additional information about how the software should behave will become clear. Exploring and writing down the behavior of the software will lead a requirements analyst to understand various aspects of the users’ needs in a new light, and additional use cases and functional requirements will start to become clear as well. As this happens, they should be written down with a name, number and summary—once they are in this form, the analyst can apply the four-step process to complete them.

The first step in developing use cases is identifying the basic ones that will be developed. The list of features in the vision and scope document is a good starting point, as there will usually be at least one use case per feature (usually more than one). This will probably not be the final set of use cases—additional ones will probably be discovered during the development of the use cases.

Many requirements analysts have found that a four-step approach is effective in developing use cases. The following script describes this approach.

Name Use Case Development Script
Purpose  A four-step approach to use case development
 Summary  This approach to developing use cases allows the information to be gathered and documented naturally, in a way that lends itself to an iterative approach of alternating iteration, documentation and verification of use cases.
 Work Products Output
Use cases
Entry Criteria A requirements analyst has received feedback from elicitation and is ready to develop use cases.
Basic Course of Events
  1. Identify the basic set of use cases. Assign a name and number to each use case.
  2. Add a rationale and summary to each use case. Identify which users will interact with each use case and add them as well. Create a master list of user categories that identifies all of the information known about each kind of user: titles, roles, physical locations, approximate number of users in the category, organizational policies they must adhere to, and anything else that makes someone part of their category. Where possible, add precondition and postcondition states to the use cases.
  3. Define the basic course of events and the alternative paths for each use case. Finish adding the precondition and postcondition states. If additional users and use cases are discovered, add them as well (starting with just a name and number, and then adding the other information as in Step 2).
  4. Verify each use case, ensuring that all paths make sense and are correct. Go through each step with user representatives to make sure that they accurately represent the way they expect the users to interact with the software. Look for any steps which are awkward for the user that could be made more efficient. Finish all use cases which were added in Step 3.
Exit Criteria The use cases are complete, and no additional information has been uncovered which may lead to additional use cases being developed. If additional use cases have been discovered, return to step 1 to fill them in.

Functional requirements define the internal workings of the software: that is, the calculations,technical details, data manipulation and processing, and other specific functionality that shows how the use cases are to be satisfied. It also contains nonfunctional requirements, which impose constraints on the design or implementation (such as performance requirements, quality standards, or design constraints).

Functional requirements

Once an initial set of use cases has been created and filled in, the requirements analyst begins documenting the functional requirements. The following table shows the template for a functional requirement.

Name Name and number of the functional requirement
Summary Brief description of the requirement
Rationale Description of the reason that the requirement is needed
Requirements The behavior required of the software
References Use cases or other functional or nonfunctional requirements that are relevant to understanding this one

The name, summary, and rationale of each functional requirement are used in the same way as those of the use cases. The behavior that is to be implemented should be described in plain English in the “Requirements” section. Most requirements are only relevant to a small number of use cases—these should be listed by name and number in the “References” section. (Some requirements are not associated with use cases.)

The core of the requirement is the description of the required behavior. It is very important to make this clear and readable. This behavior may come from organizational or business rules, or it may be discovered through elicitation sessions with users, stakeholders, and other experts within the organization. Many requirements will be uncovered during the use case development. When this happens, the requirements analyst should create a placeholder requirement with a name and summary, and research the details later, to be filled in when they are better known.

The following table shows an example of a requirement that might be discovered during the development of the search-and-replace use case below.

Name FR-4: Case insensitivity in search-and-replace
Summary The search-and-replace feature must have case sensitivity in both the search and the replacement.
Rationale A user will often search for a word that is part of a sentence, title, heading, or other kind of text that is not all lowercase. The search-and-replace function needs to be aware of that, and give the user the option to ignore it.
Requirements When a user invokes the search-and-replace function, the software must give the option to do a case sensitive search.By default, the search will match any text that has the same letters as the search term, even if the case is different. If the user indicates that the search is to be done with case-sensitivity turned on, then the software will only match text in the document where the case is identical to that of the search term.During a search and replace, when the software replaces original text in the document with the replacement text specified by the user, the software retains the case of the original text as follows:

  • If the original text was all uppercase, then the replacement text must be inserted in all uppercase.
  • If the original text was all lowercase, then the replacement text must be inserted in all lowercase.
  • If the original text had the first character uppercase and the rest of the characters lowercase, then the replacement text must reflect this case as well.
  • If the original text was sentence case (where the first letter of each word is uppercase), then the replacement text must be inserted in sentence case.
  • In all other cases, the replacement text should be inserted using the case specified by the user.
References UC-8: Search

Requirements vs. Design

This handout illustrates the differences between needs, requirements and design.

Requirements vs. Design (PDF)
Requirements vs. Design (MS Word)

Design and Programming Tools

There are many tasks over the course of a software project which can be automated. Unit tests are a good example of automation—before programmers started using automated unit tests, they had to manually verify each function and user interface element before delivering a build. By automating unit tests, the programmers were able to make them much less time-consuming task, and as a result many more programmers take the time to build unit tests.

But unit tests are not the only manual programming task that can be automated. Automation can ensure that the software is built the same way each time, that the team sees every change made to the software, and that the software is tested and reviewed in the same way every day so that no defects slip through or are introduced through human error. A project manager can help the programmers avoid chronic quality problems by adopting some of these tools.

Version Control

The version control tool recommended in Applied Software Project Management is Subversion, a free and open source version control system. It is available from for many operating systems and platforms, including Linux, BSD, Solaris, BeOS, OS/2, Mac OS X and Windows. Subversion provides many advanced features for bringing source code under control, but it takes only a few basic commands for a programming team to use a simple version control repository effectively. Subversion can be downloaded from A free book about Subversion, Version Control with Subversion, is published by O’Reilly and available at Subversion installation procedure does not install a graphical user interface—all functions are accessed through command-line programs. There are graphical utilities and web interfaces which work with Subversion, including TortoiseSVN, ViewCVSand SmartSVN.There are many other version control tools available. A list of popular ones can be found at the bottom of the Revision Control Wikipedia page.

Unit Testing

The most common (and effective) way for programmers to do unit testing is to use a framework, a piece of software that automatically runs the tests and reports the results. A framework typically allows a programmer to write a set of test cases for each unit. Most frameworks provide an automated system for executing a suite of unit tests and reporting the results. This allows a full battery of unit tests to be executed automatically at any time with little or no effort. Unit testing frameworks are available for most modern programming languages.

 Language Framework Name (URL)
Java  JUnit (
Visual Studio .NET  NUnit (
C  CUnit (
 C++  CppUnit (
 SmallTalk  SUnit (
 Perl  Test (
 Python  PyUnit (
 Borland Delphi  DUnit (

Automated Build Tools

When projects become complex and require many steps to build, it’s easy for programmers to forget a step. A programmer may build a version of the software which is missing a library, or is compiled with incorrect options. What’s more, some programming teams have discovered that, as their build process becomes more and more complex, they have to dedicate more of a senior team member’s time generating new builds on a regular basis, which can cause delays in the project. Eventually it becomes difficult for the team to even generate a reproducible build. When the build is delivered to users, are often defects which can be traced back to missing libraries, or to required files which should have been included.

There are many automated build tools that address all of the problems caused by an unpredictable and difficult-to-reproduce build process. Popular ones include:

Automated Project Monitoring

One of the most important ways a software project can be automated is with a development monitoring system. Two of the most popular ones are CruiseControl ( and TinderBox (, both of which are free and open source. These tools allow a project team to set up a set of tasks to be run automatically on a schedule. These tasks include:

  • Retrieving the latest build from the version control system, building it, copying it to a folder, and reporting any build warnings or errors
  • Running automated unit tests, generating a test report and reporting critical failures
  • Running automated code review tools and reporting any warnings or rule violations
  • Listing any changes which have been committed and by whom, including links to code listings for the changes
  • E-mailing results as text or visual reports (or sent via SMS text messages or some other communications system)

Refactoring and Unit Testing

This handout gives examples of refactoring and unit testing in Java.

Refactoring and Unit Testing (PDF)
Refactoring and Unit Testing (MS Word)

Test Plans and Test Cases

Throughout the entire software project, the team does many things to find and prevent defects. Once the software has been built, it’s time to look back and make sure that it meets the requirements. The goal of software testing is to make sure that the product does what the users and stakeholders need it to do. Software testers review the final product to make sure that the initial requirements have been met.

In software testing, quality is defined as “conformance to requirements.” Every use case, functional requirement, and other software requirement defines a specific behavior that the software must exhibit. When the software does not behave the way that the requirements say it must behave, that is a defect. This means that software testers are responsible for figuring out whether the software that was produced by the team behaves in the way that the requirements it was built from say that it should.

The goal of test planning is to establish the list of tasks that, if performed, will identify all of the requirements that have not been met in the software. The main work product is the test plan. There are many standards that can be used for developing test plans. The following table shows the outline of a typical test plan. (This outline was adapted from IEEE 829, the most common standard for software test plans.)


A description of the purpose of the application under test.

Features to be tested

A list of the features in the software that will be tested. It is a catalog of all of the test cases (including a test case numberand title) that will be conducted, as well as all of the base states.

Features not to be tested

A list of any areas of the software that will be excluded from the test, as well as any test cases that were written but will not be run.


A description of the strategies that will be used to perform the test.

Suspension criteria and resumption requirements

Suspension criteria are the conditions that, if satisfied, require that the test be halted. Resumption requirements are the conditions that are required in order to restart a suspended test.

Environmental Needs

A complete description of the test environment or environments. This should include a description of hardware, networking, databases, software, operating systems, and any other attribute of the environment that could affect the test.


An estimated schedule for performing the test. This should include milestones with specific dates.

Acceptance criteria

Any objective quality standards that the software must meet, in order to be considered ready for release. This may include things like stakeholder sign-off and consensus, requirements that the software must have been tested under certain environments, minimum defect counts at various priority and severity levels, minimum test coverage numbers, etc.

Roles and responsibilities

A list of the specific roles that will be required for people in the organization, in order to carry out the test. This list can indicate specific people who will be testing the software and what they are responsible for.

The test plan represents the overall approach to the test. In many ways, the test plan serves as a summary of the test activities that will be performed. It shows how the tests will be organized, and outlines all of the testers’ needs that must be met in order to properly carry out the test. The test plan is especially valuable because it is not a difficult document to review, so the members of the engineering team and senior managers can inspect it. The bulk of the test planning effort is focused on creating the test cases. A test case is a description of a specific interaction that a tester will have, in order to test a single behavior of the software. Test cases are very similar to use cases, in that they are step-by-step narratives that define a specific interaction between the user and the software. However, unlike use cases, they contain references to specific features of the user interface. The test case contains actual data that must be entered into the software and the expected result that the software must generate.

A typical test case includes these sections, usually laid out in a table:

  • A unique name and number
  • A requirement that this test case is exercising
  • Preconditions that describe the state of the software before the test case (which is often a previous test case that must always be run before the current test case)
  • Steps that describe the specific steps that make up the interaction
  • Expected results that describe the expected state of the software after the test case is executed

The following table shows an example of a test case that would exercise one specific behavior in the search and replace requirement. This requirement specified how a search-and-replace function must deal with case sensitivity. One part of that requirement said, “If the original text was all lowercase, then the replacement text must be inserted in all lowercase.”

Name TC-47: Verify that lowercase data entry results in lowercase insert
Requirement FR-4 (Case sensitivity in search-and-replace), bullet 2
Preconditions The test document TESTDOC.DOC is loaded (base state BS-12).
  1. Click on the “Search and Replace” button.
  2. Click in the “Search Term” field.
  3. Enter This is the Search Term.
  4. Click in the “Replacement Text” field.
  5. Enter This IS THE Replacement TeRM.
  6. Verify that the “Case Sensitivity” checkbox is unchecked.
  7. Click the OK button.
 Expected Results
  1. The search-and-replace window is dismissed.
  2. Verify that in line 38 of the document, the text this is the search term has been replaced by this is the replacement term.
  3. Return to base state BS-12.



Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.