All About Unit Testing, Integration Testing, And Functional Testing
For any software application, both Unit testing, as well as Integration testing, is very important as each of them employs a unique process to test a software application.
Unit, integration, and functional testing are crucial components of software application testing. Each of these employs a distinct and unique process to test the application. However, the most important remains functional testing and functional regression testing. Unit or integration testing cannot replace this, either by itself or collectively. While unit testing involves testing individual modules of an application, isolated integration testing checks if different modules are working together as a group. Finally, functional testing checks whether the system operates the way it is supposed to.
Together, these constitute an application that is bug-free and smooth for the end-user. Functionality is related to integration tests. The latter is performed only when the former has yielded desired results. However, successful automated functional testing signifies that the entire app is running smoothly.
As the name suggests, this level involves testing a ‘Unit’.
Here unit can be the smallest part of an application that is testable, be it the smallest individual function, method, etc. Software developers are the ones who write the unit test cases. The aim here is to match the requirements and the unit’s expected behavior.
Below are a few important points about unit testing and its benefits:
· Unit testing is done before Integration testing by software developers using white box testing techniques.
· Unit testing does not only check the positive behavior i.e. the correct output in case of valid input, but also the failures that occur with invalid input.
· Finding issues/bugs at an early stage is very useful and it reduces the overall project costs. As Unit testing is done before the integration of code, issues found at this stage can be resolved very easily and their impact is also very less.
· A unit test tests small pieces of code or individual functions so the issues/errors found in these test cases are independent and do not impact the other test cases.
· Another important advantage is that the unit test cases simplify and make testing of code easier. So, it becomes easier to resolve the issues at a later stage too as only the latest change in the code is to be tested.
· Unit testing saves time and cost, and it is reusable and easy to maintain.
JUnit (Java framework), PHPUnit (PHP framework), NUnit (.Net framework) etc. are popular unit testing tools that are used for different languages.
Integration testing is testing the integration of different parts of the system together. Two different parts or modules of the system are first integrated and then integration testing is performed.
The aim of integration testing is to check the functionality, reliability, and performance of the system when integrated.
Integration testing is performed on the modules that are unit tested first and then integration testing defines whether the combination of the modules gives the desired output or not.
Integration testing can either be done by independent testers or by developers too.
There are 3 different types of Integration testing approaches. Let us discuss each one of them briefly:
a) Big Bang Integration Approach
In this approach, all the modules or units are integrated and tested as a whole at one time. This is usually done when the entire system is ready for integration testing at a single point of time.
Please do not confuse this approach of integration testing with system testing, only the integration of modules or units is tested and not the whole system as it is done in system testing.
The big bang approach’s major advantage is that everything integrated is tested at one time.
One major disadvantage is that it becomes difficult to identify the failures.
Example: In the figure below, Unit 1 to Unit 6 are integrated and tested using the Big bang approach.
b) Top-Down Approach
Integration of the units/modules is tested from the top to bottom levels step by step.
The first unit is tested individually by writing test STUBS. After this, the lower levels are integrated one by one until the last level is put together and tested.
The top-down approach is a very organic way of integrating as it is consistent with how things happen in the real environment.
The only concern with this approach is that the major functionality is tested at the end.
c) Bottom-Up Approach
Units/modules are tested from bottom to top level, step by step, until all levels of units/modules are integrated and tested as one unit. Stimulator programs called DRIVERS are used in this approach. It is easier to detect issues or errors at the lower levels.
The major disadvantage of this approach is that the higher-level issues can only be identified at the end when all the units have been integrated.
A black box testing technique, where the functionality of the application is tested to generate the desired output on providing a certain input is called ‘Functional testing’.
In our software testing processes, we do this by writing test cases as per the requirements and scenarios. For any functionality, the number of test cases written can vary from one to many.
Test cases basically comprise of the following parts:
· Prerequisites (if any)
· Test case input steps
· Test data (if any)
· Expected output
· Notes (if any)
“Requirement-Based” and “Business scenario-based” are the two forms of functional testing that are carried out.
In Requirement based testing, test cases are created as per the requirement and tested accordingly. In a Business scenario based functional testing, testing is performed by keeping in mind all the scenarios from a business perspective.
However, the major disadvantage of functional testing is the probable redundancy in testing and the possibility of missing some logical errors.
The main differences between the three
The differences between unit testing, integration testing, and functionality testing can be divided into the following categories:
Purpose: Unit testing checks the most basic unit of the application, each module, individually. Integration testing checks two or more modules combined to perform tasks. Functional automation testing tests the behavior of the application when it functions as a whole.
Complexity: Unit testing is simple in its language and is easy to write since it includes the smallest of codes. While integration testing is slightly more complex compared to unit tests, functionality testing constitutes the most complicated of the batch.
Testing techniques: Unit testing involves white box testing techniques. Functionality regression testing consists of only black-box testing techniques. Integration testing uses both black and white box techniques- also called grey-box testing.
Errors covered: Unit tests can cover issues that occur with frequency in different modules. It nullifies the chance of any problem going unnoticed. In the case of integration testing, the errors covered include bugs that occur when integrating various modules. Issue escape is a rare occurrence. For automated functionality testing, issues that hinder the performance of an application are identified. Scenario-based problems are also tested here. There is the most chance of issue escape here because the list of tests to be run is infinite.
Unit Testing Vs Integration Testing Vs Functional Testing
Unit testing means testing individual modules of an application in isolation (without any interaction with dependencies) to confirm that the code is doing things right.
Integration testing means checking if different modules are working fine when combined together as a group.
Functional testing means testing a slice of functionality in the system (which may interact with dependencies) to confirm that the code is doing the right things.
Functional tests are related to integration tests, however, they signify the tests that check the entire application’s functionality with all the code running together, nearly a super integration test.
Unit testing considers checking a single component of the system whereas functionality testing considers checking the working of an application against the intended functionality described in the system requirement specification. On the other hand, integration testing considers checking integrated modules in the system.
And, most importantly, to optimize the return on investment (ROI), your code base should have as many unit tests as possible, fewer integration tests and the least number of functional tests.
Now, let us now take a technical example of a login page:
Almost every web application requires its users/customers to log in. For that, every application has to have a “Login” page that has these elements:
· Login/Sign in Button
For Unit Testing, the following may be the test cases:
· Field length – username and password fields.
· Input field values should be valid.
· The login button is enabled only after valid values (Format and lengthwise) are entered in both fields.
For Integration Testing, the following may be the test cases:
· The user sees the welcome message after entering valid values and pushing the login button.
· The user should be navigated to the welcome page or home page after a valid entry and clicking the Login button.
Now, after unit and integration testing are done, let us see the additional test cases that are considered for functional testing:
1. The expected behavior is checked, i.e. is the user able to log in by clicking the login button after entering a valid username and password values?
2. Is there a welcome message that is to appear after a successful login?
3. Is there an error message that should appear on an invalid login?
4. Are there any stored site cookies for login fields?
5. Can an inactivated user log in?
6. Is there any ‘forgot password’ link for the users who have forgotten their passwords?
There are much more such cases that come to the mind of a functional tester while performing functional testing. But a developer cannot take up all cases while building Unit and Integration test cases.
To conclude, we must understand that these processes are interconnected and correlated. Unit testing is imperative to ensure that your software is working seamlessly. Unit testing facilitates flawless paths and lines of code. This, in turn, must be followed by integration tests to make sure that separate units can work together cohesively. Finally, all of the above must be followed by functional tests to deliver a polished app. Functional regression testing also needs to be performed if the application in question is an existing software where updates are being implemented.