34 Software Testing – Lecture I
Testing is a process of identifying defects. It is used to develop test cases and test data. A test case is a formal description of a starting state. One or more events to which the software must respond. Test data is a set of starting states and events used to test a module, group of modules, or entire system. Testing begins at module level and works outward towards the integration of entire computer based system. Different testing techniques are required at different points in time. Testing is conducted by the s/w developer and ITG (Independent Test Group) for large projects. Testing and Debugging are different and Debugging is essential in any testing strategy.
A strategy for software testing integrates the design of software test cases into a well-planned series of steps that result in successful development of the software. The strategy provides a road map that describes the steps to be taken, when, and how much effort, time, and resources will be required. The strategy incorporates test planning, test case design, test execution, and test result collection and evaluation. The strategy provides guidance for the practitioner and a set of milestones for the manager. Because of time pressures, progress must be measurable and problems must surface as early as possible. Software testing is part of a broader group of activities called verification and validation that are involved in software quality assurance.
Verification (Are the algorithms coded correctly?)
The set of activities that ensure that software correctly implements a specific function or algorithm
Validation (Does it meet user requirements?)
The set of activities that ensure that the software that has been built is traceable to customer requirements.
Testing should aim at “breaking” the software. The common misconceptions are the developer of software should do no testing at all and the software should be given to a secret team of testers who will test it unmercifully. The testers get involved with the project only when the testing steps are about to begin. The independent test group removes the inherent problems associated with letting the builder test the software that has been built. It also removes the conflict of interest that may otherwise be present. It works closely with the developer during analysis and design to ensure that thorough testing occurs.
Unit Testing:
Concentrates on each component/function of the software as implemented in the source code. Exercises specific paths in a component’s control structure to ensure complete coverage and maximum error detection. Components are then assembled and integrated.
Integration Testing:
Focuses on the design and construction of the software architecture. Focuses on inputs and outputs, and how well the components fit together and work together.
Validation Testing:
Requirements are validated against the constructed software. Provides final assurance that the software meets all functional, behavioral, and performance requirements.
System Testing:
The software and other system elements are tested as a whole. Verifies that all system elements (software, hardware, people, databases) mesh properly and that overall system function and performance is achieved.
When is Testing Complete? There is no definitive answer to this question. Every time a user executes the software, the program is being tested. Sadly, testing usually stops when a project is running out of time, money, or both. One approach is to divide the test results into various severity levels. Then consider testing to be complete when certain levels of errors no longer occur or have been repaired or eliminated. Specify product requirements in a quantifiable manner long before testing commences.
Ensuring a Successful Software Test Strategy can be achieved by understanding the user of the software (through use cases) and develop a profile for each user category. Develop a testing plan that emphasizes rapid cycle testing to get quick feedback to control quality levels and adjust the test strategy. This helps to build robust software that is designed to test itself and can diagnose certain kinds of errors. It uses effective formal technical reviews as a filter prior to testing to reduce the amount of testing required. Conduct formal technical reviews to assess the test strategy and test cases themselves. Develop a continuous improvement approach for the testing process through the gathering of metrics.
Unit testing focuses testing on the function or software module. It concentrates on the internal processing logic and data structures. It is simplified when a module is designed with high cohesion. This reduces the number of test cases. Allows errors to be more easily predicted and uncovered. Concentrates on critical modules and those with high cyclomatic complexity when testing resources are limited.
Targets for Unit Test Cases includes:
Module interface:
Ensure that information flows properly into and out of the module.
Local data structures:
Ensure that data stored temporarily maintains its integrity during all steps in an algorithm execution.
Boundary conditions:
Ensure that the module operates properly at boundary values established to limit or restrict processing.
Independent paths (basis paths):
Paths are exercised to ensure that all statements in a module have been executed at least once.
Common Computational Errors in Execution Paths includes:
Misunderstood or incorrect arithmetic precedence.
Mixed mode operations (e.g., int, float, char).
Incorrect initialization of values.
Precision inaccuracy and round-off errors.
Incorrect symbolic representation of an expression (int vs. float).
Comparison of different data types.
Incorrect logical operators or precedence.
Expectation of equality when precision error makes equality unlikely (using == with float types).
Incorrect comparison of variables.
Improper or nonexistent loop termination.
A driver can be defined as a simple main program that accepts test case data, passes such data to the component being tested, and prints the returned results. Whereas Stubs Serve to replace modules that are subordinate to (called by) the component to be tested. It uses the module’s exact interface, may do minimal data manipulation, provides verification of entry, and returns control to the module undergoing testing.
Drivers and stubs both represent overhead, both must be written but don’t constitute part of the installed software product.