Towards a robust testing future: Unit Vs Integration Testing
Software Testing involves the validation and verification of the system functionality against the requirements. Various tests can be carried out to validate whether the system performs as required. In this article, we will be diving deep into two of the most fundamental types of testing: Unit and Integration Testing.
Unit testing involves testing individual components or units in software development.
The purpose is to validate that each unit of the software performs as designed. A unit is the smallest testable part of any software. It usually has one or a few inputs and usually a single output.
With unit tests, we get coverage. Coverage only shows us the number of lines in our code that are executed when we are running our tests but not exactly the bugs or the robustness of our solutions. As a matter of fact, it is useless to measure the robustness of a codebase using coverage as we can have high coverage without proper testing. Testing is about the quality and not the quantity and as Goodhart’s law goes When a measure becomes a target, it ceases to be a good measure.
When it comes to test execution and application robustness, quality and not the quantity of tests is what matters and coverage or a high number of unit tests do not seal the deal.
Do not read me wrong I am not saying unit-tests are entirely useless. I am just saying that you require more than unit tests to gain confidence in the performance of your applications in the real world. To solve the deficiencies created by unit testing, integration testing is used to tie up different units and ensure that they perform as expected when wired up together.
The level of testing involves combining a group of software units and testing them as a group. Integration testing should always be done once the unit-testing phase is done.
The purpose of this level of testing is to expose faults in the interaction between integrated units.
Integration tests are higher in the testing pyramid than unit-tests and have a goal of ensuring that processes and not units are tested. Writing Integration tests might involve mocking responses using fixtures, trying out user-centric scenarios such as reloads, intentional error introduction and even testing out edge-case scenarios during usage.
Integration tests cover the scenarios that are too complicated for unit testing to capture but that would also be an overkill for the end to end testing process. Integration tests could involve a process such as:
- Navigate to the login screen
- Enter login details
- Navigate to the dashboard
- Reload to ensure the application preserves the state of the logged in user.
- Validate user is still logged in
While the above process is simple and almost obvious it is almost impossible to achieve using unit testing. The example, however, exemplifies the use of the application in the real world and uses various units to achieve the result. Integration tests, therefore, serve the purpose of bridging the gap between user-scenarios that involve different units and components grouped together and functionality written for the sole performance of the application (sole units and components). Truth be told, integration tests on their own cannot guarantee the application robustness and they are too part of the pyramid of what makes up a good system.
Both integration and unit tests are important for any software where the guarantee of usage and robustness needs to be present. In all instances, however, the test scenarios and the test cases are what determine the quality of tests and not the coverage. Next time you write your application remember that without integration testing all you are doing is exemplifying the above gif. Happy Testing!