4.5.3 The project manager shall test the software against its requirements.
A best practice for Class A, B, and C software projects is to have formal software testing planned, conducted, witnessed, and approved by an independent organization outside of the development team.
1.2 Applicability Across Classes
Key: - Applicable | - Not Applicable
A & B = Always Safety Critical; C & D = Sometimes Safety Critical; E - F = Never Safety Critical.
Software testing is required to ensure that the software meets the agreed requirements and design, the application works as expected, the application doesn’t contain serious bugs and the software meets its intended use as per user expectations.
Per section 3.2 of the IEEE 730-2014 IEEE Standard for Software Quality Assurance Processes 469, “software testing is an activity in which a system or component is executed under specified conditions, the results are observed or recorded, and an evaluation is made of some aspect of the system or component”. Per the ISO/IEC TR 19759:2005 Software Engineering -- Guide to the Software Engineering Body of Knowledge (SWEBOK), software testing is “the dynamic verification of the behavior of a program on a finite set of test cases, suitably selected from the usually infinite executions domain, against the expected behavior”.
The developer performs software testing to demonstrate to the acquirer that the software item requirements have been met, including the interface requirements. If the software item is developed in multiple builds, its software item qualification testing will not be completed until the final build for that software item. The persons responsible for qualification testing of a given software item should not be the persons who performed detailed design or implementation of the at software item. This does not preclude persons who performed detailed design or implementation of the at software item from contributing to the process.
Software testing is very important for the following reasons:
- Software testing is really required to point out the defects and errors that were made during the development phases.
- Ensure reliability in the application.
- Verify the quality of the product.
- Testing is required for an effective performance of software application or product.
One intent of software testing is to test all paths through the code—every decision, and every nominal and off-nominal path—by executing test cases. Code coverage metrics identify additional tests that need to be added to the test run. Code coverage tools monitor the path the software executes and can be used during test runs to identify code paths that were not executed by any test. By analyzing these missed areas, tests can be identified and implemented to execute the missed path. It is very difficult to get 100% coverage due to off-nominal and hardware issues not possible or not advisable to execute during a test run (e.g., radiation effects, hardware failures). Code coverage metrics can also identify sections of orphaned or unused code (dead code).
Code coverage can require the code to be compiled and instrumented in a specific manner and then executed in the test environments to indicate the code coverage of the tests. This instrumentation invalidates any functional acceptance testing, so acceptance testing would require test runs without modification. Code coverage should be verified as part of the in-line development test schedule. Code coverage of software-only unit tests would minimally impact the in-line development test schedule and could be recorded as part of the code coverage metrics. New hardware-only coverage tools can provide the metrics without intrusive instrumentation of the code.
Consider using code coverage as a part of a project’s software testing metrics. Code coverage (also referred to as structural coverage analysis) is an important verification tool for establishing the completeness and adequacy of testing. Traceability between code, requirements and tests is complemented by measuring structural coverage of the code when the tests are executed. Where coverage is less than 100%, this points to:
- Code that is not traceable to requirements.
- Inadequate tests.
- Incomplete requirements.
- A combination of the above.
When using requirements-based testing, 100% code coverage means that, subject to the coverage criteria used, no code exists which cannot be traced to a requirement. For example, using function coverage, every function is traceable to a requirement (but individual statements within the coverage may not be). What 100% code coverage does not mean is:
- The code is correct. The test cases which, when aggregated, exercise every line of code. This is not sufficient to show there are no bugs. As long ago as 1969 Edsger Dijkstra noted “testing shows the presence of bugs, not their absence” – in other words, just because testing doesn’t show any errors, it doesn’t mean they are not present.
- The software requirements are correct. This is determined through validation of the requirements with the customer.
- 100% of the requirements have been tested. Merely achieving 100% code coverage isn’t enough. This is only true if the project achieves 100% code coverage AND the project has a test for 100% of the requirements AND every test passes.
- The compiler translated the code correctly. The compiler might be inserting errors which cause incorrect results in some situations (ones the project hasn’t tested for).
- 100% of the object code is covered. Even when all statements and conditions of the source code are being executed, the compiler can introduce additional structures into the object code.
Consider requiring code-coverage tools for determining testing completeness and identification of untested code automates testing quality and can provide metrics for determining test completeness.
Additional Software Test Guidance
Per NASA-GB-8719.13, NASA Software Safety Guidebook 276, "Testing serves several purposes: to find defects; to validate the system or an element of the system; and to verify functionality, performance, and safety requirements. The focus of testing is often on the verification and validation aspects. However, defect detection is probably the most important aspect of testing. While you cannot test quality into the software, you can certainly work to remove as many defects as possible."
Software testing has many levels, including unit testing, integration testing, and system testing, which can include functionality, performance, load, stress, safety, and acceptance testing. While unit testing is typically performed by the development team, some testing, such as integration, system or regression testing may be performed by a separate and/or independent test group.
Keep in mind that formal testing, such as acceptance testing, is to be witnessed by an external organization, such as software assurance (see NASA-STD-8739.8, Software Assurance Standard 278).
The following basic principles of testing come from NASA-GB-8719.13, NASA Software Safety Guidebook 276:
- All tests need to be traceable to the requirements and all requirements need to be verified by one or more methods (e.g., test, demonstration, inspection, analysis).
- Tests need to be planned before testing begins. Test planning can occur as soon as the relevant stage has been completed. System test planning can start when the requirements document is complete.
- The "80/20" principle applies to software testing. In general, 80 percent of errors can be traced back to 20 percent of the components. Anything you can do ahead of time to identify components likely to fall in that 20 percent (e.g., high risk, complex, many interfaces, demanding timing constraints) will help focus the testing effort for better results.
- Start small and then integrate into the larger system. Finding defects deep in the code is difficult to do at the system level. Such defects are easier to uncover at the unit level.
- You can't test everything. Exhaustive testing cannot be done except for the most trivial of systems. However, a well-planned testing effort can test all parts of the system. Missing logic paths or branches may mean missing important defects, so test coverages need to be determined.
- Testing by an independent party is most effective. It is hard for developers to see their own bugs. While unit tests are usually written and run by the developer, it is a good idea to have a fellow team member review the tests. A separate testing group will usually perform the other tests. An independent viewpoint helps find defects, which is the goal of testing.
NASA-GB-8719.13, NASA Software Safety Guidebook 276, includes a chapter on testing with a focus on safety testing. Some general testing highlights of that chapter include:
- Software testing beyond the unit level (integration and system testing) is usually performed by someone other than the developer, except in the smallest of teams.
- Normally, software testing ensures that the software performs all required functions correctly, and can exhibit graceful behavior under anomalous conditions.
- Integration testing is often done in a simulated environment, and system testing is usually done on the actual hardware. However, hazardous commands or operations need to be tested in a simulated environment first.
- Any problems discovered during testing need to be analyzed and documented in discrepancy reports and summarized in test reports.
- Create and follow written test procedures for integration and system testing.
- Perform regression testing after each change to the system.
- Prepare Test Report upon completion of a test.
- Verify that commercial off the shelf (COTS) software operates as expected.
- Follow problem reporting and corrective action procedures when defects are detected.
- Perform testing in a controlled environment using a structured test procedure and monitoring of results or in a demonstration environment where the software is exercised without interference.
- Analyze tests before use to ensure adequate test coverage.
- Analyze test results to verify that requirements have been satisfied and that all identified hazards are eliminated or controlled to an acceptable level of risk.
Other useful practices include:
- Plan and document testing activities to ensure all required testing is performed.
- Have test plans, procedures, and test cases inspected and approved before use.
- Use a test verification matrix to ensure coverage of all requirements.
- Consider dry running test procedures in offline labs with simulations prior to actual hardware/software integration tests.
- Consider various types of testing to achieve more comprehensive coverage. (See Software QA and Testing Frequently-Asked-Questions 207 or NASA-GB-8719.13, NASA Software Safety Guidebook 276, for a list with descriptions.)
- When time and resources are limited, identify areas of highest risk and set priorities to focus effort where the greatest benefit will be achieved with the available resources. (See Software QA and Testing Frequently-Asked-Questions 207 or NASA-GB-8719.13, NASA Software Safety Guidebook 276, for suggested risk analysis considerations.)
- As necessary and appropriate, include support from the software development and/or test team when performing formal testing of the final system. Support could include:
- Identifying system test requirements unique to software.
- Providing input for software to system test procedures.
- Providing software design documentation.
- Providing software test plans and procedures.
While NASA Centers typically have their own procedures and guidance, NASA-GB-8719.13, NASA Software Safety Guidebook 276, lists and describes the following testing which needs to be considered when planning any software test effort:
- Functional system testing.
- Stress testing.
- Stability tests.
- Resistance to failure testing.
- Compatibility tests.
- Performance testing.
The following chart shows a basic flow for software testing activities from planning through maintenance. Several elements of this flow are addressed in related requirements in this Handbook (listed in the table at the end of this section).
Tools which may be useful when performing software testing include the following, non-exhaustive list. Each project needs to evaluate and choose the appropriate tools for the testing to be performed for that project.
- Software analysis tools.
- Reverse engineering, code navigation, metrics, and cross-reference tools.
- Coding standards checkers.
- Memory management tools.
- Screen capture utilities.
- Serial interface utilities.
- Telemetry display utilities.
- Automated scripts.
NASA users should consult Center Process Asset Libraries (PALs) for Center-specific guidance and resources related to software testing.
NASA-specific planning information and resources for software testing are available in Software Processes Across NASA (SPAN), accessible to NASA users from the SPAN tab in this Handbook.
Additional guidance related to software testing, including specifics of plan, procedure, and report contents may be found in the following related requirements in this Handbook:
4. Small Projects
Software testing is required regardless of project size.
- International Space Station Program/Hardware-Software/Qualification Testing-Verification and ValidationPublic Lessons Learned Entry: 1104.
NASA users find this in the Tools Library in the Software Processes Across NASA (SPAN) site of the Software Engineering Community in NEN.
The list is informational only and does not represent an “approved tool list”, nor does it represent an endorsement of any particular tool. The purpose is to provide examples of tools being used across the Agency and to help projects and centers decide what tools to consider.
6. Lessons Learned
The NASA Lessons Learned database contains the following lessons learned related to the importance of and potential issues related to software testing:
- International Space Station Program/Hardware-Software/Qualification Testing-Verification and Validation (Issues related to using software before completion of testing.) Lesson Number 1104: "Some hardware is being used in MEIT before it has completed qualification testing. Software is also often used before its verification and validation is complete. In both cases, modification to the hardware or software may be required before certification is completed, thereby potentially invalidating the results of the initial MEIT testing." 537
- International Space Station Program/Hardware-Software/Integration Testing (The importance of end user involvement in the testing process.) Lesson Number 1106: "Astronaut crew participation in testing improves fidelity of the test and better familiarizes the crew with systems and procedures." 538
- MPL Uplink Loss Timer Software/Test Errors (1998) (The importance of recognizing and testing high risk aspects of software.) Lesson Number 0939: 1) "Recognize that the transition to another mission phase (e.g. from EDL to the landed phase) is a high risk sequence. Devote extra effort to planning and performing tests of these transitions. 2) Unit and integration testing should, at a minimum, test against the full operational range of parameters. When changes are made to database parameters that affect logic decisions, the logic should be re-tested." 530
- Deep Space 2 Telecom Hardware-Software Interaction (1999) (Considerations for performance testing.) Lesson Number 1197: The Recommendation states: "To fully validate performance, test integrated software and hardware over the flight operational temperature range... ['test as you fly, and fly as you test...'"] 545
- Probable Scenario for Mars Polar Lander Mission Loss (1998) (Testing failures.) Lesson Number 0938: "1) Project test policy and procedures should specify actions to be taken when a failure occurs during test. When tests are aborted, or known to have had flawed procedures, they must be rerun after the test deficiencies are corrected. When test article hardware or software is changed, the test should be rerun unless there is a clear rationale for omitting the rerun. 2) All known hardware operational characteristics, including transients and spurious signals, must be reflected in the software requirements documents and verified by test." 529