Software testing is an important phase in the Software Development Life Cycle (SDLC). It ensures that the software product is reliable, performs as expected, and meets user requirements. According to Robert Glass, the most important thing is user satisfaction.So, to make a compliant product as per the user requirements and needs, we need testing to ensure the quality of software is maintained and there are no defects in the software when it is made available to the end users.
Testing is usually performed in multiple levels, starting from small code units to the complete system, to catch errors as early as possible.
Major types of Testing
Even though there are many types of testing, we will focus on the major three listed below :
Unit Testing
Integration Testing
System Testing
Unit Testing
Unit Testing focuses on testing the smallest individual parts of the software usually functions, methods, or classes to ensure each component works correctly in isolation.The main goal is to verify that each unit performs as intended, independent of other parts of the system. It is done by the developers during the coding/development phase.
Example : Suppose you are developing a calculator app, testing whether the add() or divide() function returns the correct result would be considered Unit Testing.
Now the problem with testing an individual component is that it may be calling some other function or dependent on some other module. Now there is a high chance that other module is not ready yet. So to test our original module, we need some fake programs known as stubs and drivers.
Stub
A stub is a fake or temporary module used to simulate a called function that has not been developed yet.
It provides dummy data or simple output to help test the main unit.
To put it simply, Stub replaces the module that your code calls.
Driver
A driver is a temporary main program used to call and test a module that is not yet connected to the main system.
It sends input to the unit and checks the output.
To put it simply, Driver replaces the module that calls your code.
Real World Example (E-Commerce Platform)
Imagine you are developing an e-commerce website.
There are three modules:
LoginModule : handles user login.
CartModule : adds and removes items.
PaymentModule : processes payments.
Case 1: Using a Stub
You want to test the CartModule, but the PaymentModule isn’t ready yet.
The Cart module needs to “call” the Payment module to process payment.
You create a stub that pretends to be the Payment module and returns a fake success message.
// Stub for PaymentModule
string processPayment(int amount) {
return "Payment Successful (Stub)";
}
So when you test the Cart module, it behaves as if the payment worked, even though the real payment system isn’t built.
Case 2: Using a Driver
Now suppose the LoginModule is not ready, but you want to test the CartModule (which normally gets called after login).
You create a driver that simulates a login and directly calls the Cart module.
// Driver for CartModule
int main() {
cout<<"Driver: Simulating Login...\n";
addToCart("Laptop", 2); // Calling the Cart module
return 0;
}
The driver acts like a test launcher to check if the Cart module works properly — without waiting for the login feature.
Tools Used
JUnit (Java)
NUnit (.NET)
PyTest (Python)
Google Test (C++)
Jest (JavaScript)
Benefits
Integration Testing
Integration Testing checks if different modules or components work together correctly after being combined. So we combine multiple modules either incrementally or all at once(not followed in real life).
Its goal is to verify the data flow between integrated modules and to identify any kinds of interface defects. Example : Continuing the calculator program, after testing the add() and subtract() functions individually, you perform integration testing to ensure they work together correctly when combined in a larger “calculator module” or with the user interface. It is done right after unit testing, and it is usually done by the testing group. (Sometimes, it involves the developers too).
Types of Integration Testing
Big Bang Approach : All modules are integrated together at once.
Incremental Approach : Modules are integrated and tested one by one:
Big Bang Approach
In the Big Bang approach, all modules are integrated at once and then tested as a complete system.
Pros:
Cons:
Example: On an e-commerce platform, the Cart, Payment, Login, and Product modules are all combined at the same time and tested together.
Incremental Approach
In the Incremental approach, modules are integrated and tested one by one.
There are two main types of Incremental Integration:
a) Top-Down Integration
Start testing from the higher-level modules and move down to lower-level modules.
Example: Test the overall Checkout module first, then integrate and test the Cart module, then the Payment module, and so on.
Note: Sometimes stubs are needed to simulate lower-level modules that aren’t ready yet.
b) Bottom-Up Integration
Start testing from the lower-level modules and move up to higher-level modules.
Example: Test the Payment module first, then Cart module, then finally the Checkout module.
Note: Sometimes drivers are used to simulate higher-level modules that call the lower ones.
Tools Used
Benefits
System Testing
System Testing evaluates the entire integrated system as a whole to verify that it meets the specified requirements.It ensures that all components and features function together properly in the target environment.
Example : In the calculator app, system testing would verify that the full app including input handling, UI, and calculations works correctly on the user’s device.
Tools Used
Selenium
LoadRunner
QTP (UFT)
JMeter
Benefits
Validates end-to-end system behavior.
Checks compatibility, usability, and performance.
Detects issues that only appear in the full system.