Applied Software Project Management – Product Engineering Practices
Tools
This is part of the supporting material from our first book, Applied Software Project Management , which was published by Oâ€TMReilly in 2005. You can see all of the material here: https://www.stellman-greene.com/applied-software-project-management/
Contents
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â€TM or stakeholdersâ€TM needs
- Somebody believes that those needs may be better satisfied with different behavior
- An inspector does not understand whatâ€TMs 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:
Software Requirements Specification (SRS)
- 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.
- Documentation: The requirements analyst creates or updates the draft of the SRS to reflect the data elicited in step 1.
- 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.
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:
This example shows a final use case for a search-and-replace function (which is numbered UC-8):
- The user indicates that the software is to perform a search-and-replace in the document.
- The software responds by requesting the search term and the replacement text.
- The user inputs the search term and replacement text and indicates that all occurrences are to be replaced.
- The software replaces all occurrences of the search term with the replacement text.
- 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.
- 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.
- 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.
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â€TM 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.
Use cases
- Identify the basic set of use cases. Assign a name and number to each use case.
- 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.
- 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).
- 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.
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.
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.
- 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.
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
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.
Automated Build Tools
When projects become complex and require many steps to build, itâ€TMs 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â€TMs 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â€TMs 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:
- Make (which ships with most Unix-like operating systems, and some IDEs)
- GNU Make
- Apache Ant
- Jam
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 (http://cruisecontrol.sourceforge.net) and TinderBox (http://www.mozilla.org/projects/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â€TMs 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.
Approach
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.
Schedule
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â€TM 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.â€
- Click on the “Search and Replace†button.
- Click in the “Search Term†field.
- Enter This is the Search Term.
- Click in the “Replacement Text†field.
- Enter This IS THE Replacement TeRM.
- Verify that the “Case Sensitivity†checkbox is unchecked.
- Click the OK button.
- The search-and-replace window is dismissed.
- Verify that in line 38 of the document, the text this is the search term has been replaced by this is the replacement term.
- Return to base state BS-12.
This site uses Akismet to reduce spam. Learn how your comment data is processed.