Validation deals with the execution of the product, where the objective is to check whether it meets the user’s requirements. Validation means detecting, detected by executing the work product, and so it is also called dynamic testing.
Validation is done at two levels:
Low Level: Unit Testing, Integration Testing High Level: Function Testing, System Testing, Acceptance Testing
Unit Testing:
Definition: Unit testing is the process of testing the smallest/individual component of a program.
A unit test is a procedure used to validate that a particular module of source code is working properly.
Objective: The objective of unit testing is to test not only the functionality of the code but also to ensure that the code is structurally sound and robust and able to respond appropriately in all conditions.
Unit Testing is also called component testing or module testing.
As it requires knowledge of the internal design of the code, it is generally done by developers. Individual components are tested to ensure that they operate correctly. It is typically used to verify control flow and data flow, memory leak problems. We can check:
- Is the number of input parameters equal to the number of arguments?
- Do parameter and argument attributes match?
- Incorrect variable name
Selective testing of execution paths is an essential task during the unit test. Test cases should be designed to uncover errors due to concurrent computations, inconceivable comparisons, or improper control flow. Among the more common errors in computations are:
- Misunderstood or incorrect arithmetic precedence.
- Mixed mode operations.
- Incorrect initialization.
- Precision inaccuracy.
- Incorrect symbolic representation of an expression.
Since a component is not a stand-alone program, a driver and/or stub software must be developed for each unit test. In most applications, a driver is nothing more than a “main program” that accepts test data, passes such data to the component (to be tested), and prints relevant results.
Stubs serve to replace modules that are subordinate to (called by) the component to be tested. A stub or “dummy Subprogram” uses the subordinate module’s interface, may do minimal data manipulation, provides verification of entry, and returns control to the module undergoing testing.
In simple terms, a driver is the calling function, and a stub is the called function. The process of building stubs and drivers is called scaffolding.
Integration Testing:
Definition: Integration testing is the process of combining and testing multiple components together.
Now, all units are tested separately in isolation, but how can we check whether they will work in the same way when they are combined together? So we go for integration testing.
Objective: Detecting interface errors and ensuring that the modules communicate properly.
Points to remember:
- It is done to assure that the software units/components operate properly when combined together. The main objective is to verify communication between units. It is normally done by developers or by the QA team.
- Errors found in integration testing are due to:
- Wrong call orders
- Wrong parameters
- Missing functions
- Overlapping functions
- Resource problems (memory, etc.)
- Configuration/Version Control
Types of Integration Testing:
- Non-Incremental:
- It is also called Big Bang Integration. In this type, all components are combined at once to form a program. The entire program is tested as a whole. The integrated result is then tested. In this method, debugging is difficult since an error can be associated with any component.
- Incremental:
- In this type, the program is constructed and tested in small increments, where errors are easier to isolate and correct. Interfaces are more likely to be tested completely, and a systematic test approach may be applied.
Types of Incremental Integration:
- Top-Down Integration:
- In this method, modules are integrated by moving downward through the control hierarchy, beginning with the main control module (main program). Modules subordinate to the main control module are incorporated into the structure in either a depth-first or breadth-first manner. Stubs and Drivers are required.
- a. Depth First Search (DFS):
- Depth-first integration integrates all components on a major control path of the program structure. In the example below, selecting the left-hand path, components MI, M2, M4 would be integrated. Next, M5 would be integrated. DFS = {[(MI+M2) +M4] +M5} +M3.
- b. Breadth-First Search (BFS):
- Breadth-first integration incorporates all components directly subordinate at each level, moving across the structure horizontally. From Fig. 1, components MI, M2, M3 would be integrated first. The next control level M4, M5 follows. BFS = {[(MI) +M2+M3] +M4+M5}
- Depending on the integration approach selected (depth/Breadth first), Drivers & Stubs are Used.
Advantage of Top-Down Integration is that it can verify major control or decision points early in the testing process. Whereas the disadvantage is that Stubs are required when performing integration testing, and generally, developing stubs is very difficult.
- Bottom-up Integration:
- Bottom-up integration testing begins construction and testing with atomic modules (i.e., components at the lowest levels in the program structure). Because components are integrated from the bottom up, processing required for components subordinate to a given level is always available, and the need for stubs is eliminated. Each component at the lowest level of the system hierarchy is tested individually first, then the next components to be tested.
- Advantage of Bottom-up against Top-Down Integration is that drivers required are much easier to develop. The disadvantage is that major control and decision problems will be identified later in the testing process.
- Sandwich Integration:
- In sandwich integration testing, both top-down and bottom-up are started simultaneously, and testing is built up from both sides. It requires a big team.