What is Integration Testing
Integration testing is the stage in the software testing process in which individual software components are brought together and tested as a group.
The purpose of integration testing is to check whether individual modules, which are already expected to have been unit tested, work together as expected.
Understanding Integration testing
Let's try to understand integration testing using a typical software module hierarchy. You can find many such real-world examples.
In the above diagram, we have nine modules: M-1 to M-9. The arrow represents a dependency: if A ⟶ B, then A depends on B. This means that code in A calls functions (also called procedures) written in B.
In the above diagram, M-5 to M-9 are self-contained i.e. they don't depend on any other module. It will be expected that their developers have written their own unit tests.
M-5, which is the logistics API would have some function like:
get_provider_cost (provider, weight, from_country, from_zip, to_country, to_zip)
This function takes in the provider (e.g. Fedex, UPS, etc.), the weight of the package, the origin and destinnation locations, and returns the shipping cost.
M-6, which is the warehouse API would have some function like
get_nearest_warehouse (items, to_country, to_zip)
This function takes the list of items and the user's location and returns the country and zip code of the nearest warehouse having those items in stock.
M-2 which is supposed to calculate the shipping cost would have something like:
function get_shipping_cost(items, provider, user) { warehouse = get_nearest_warehouse(items, user.country, user.zip); weight = get_weight(items); return get_provider_cost(provider, weight, warehouse.country, warehouse.zip, user.country, user.zip); }
Integration testing of M-5 and M-6 will mean writing test cases that mimic M-2's behaviour.
There are different ways to do integration testing as we will see later in the document.
Why Integration Testing?
Let's continue with the above example. M-5 and M-6 modules were unit tested and developers were happy.
Sadly, the integration tests failed! On investigation the following issues were found:
- The
get_nearest_warehouse
function assumed that country would be 2 character format (e.g. US) when it was actually supposed to be in 3 character format (e.g. USA). - The
get_provider_cost
function assumed the weight would be in kilograms but it was supposed to be in grams. - The
get_weight
function returned the correct weight but the items list was cleared in the process.
It was integration testing exposed the issues when individually unit-tested modules were brought together.
Types of Integration Testing
Refer to the module hierarchy figure in the earlier section. We will use that to explain the different approaches.
Big-Bang Testing
In the big-bang approach, you wait for all code to be written and then test the top level module.
In our example, test cases will be writted only for M-1.
Advantage: Lesser code. Suitable for small systems
Disadvantage: Testing can't commence till all modules are written. Difficult to find out the offending module if a test case fails.
Top-Down Testing
Top-Down Integration Testing is a strategy in which the higher level modules are tested before the lower level modules. Dummy code (also called stubs) is often used to simulate the behaviour of the lower-level modules that are not yet developed.
In our example, the order of testing will be M-1 first, followed by M-2, M-3 and M-4, followed by the remaining modules.
Advantage: Faster exposure to design flaws.
Disadvantage: Need a lot of stubs
Bottom-Up Testing
Bottom-Up integration testing is a strategy in which the lower level modules are tested first, followed by testing of modules one level higher. This continues until all modules at the topmost level are tested.
In our example, the order of testing will be M-5 to M-9 first, followed by M-2 to M-4, followed by M-1.
Advantage: Easier to write and can be developed concurrently with the modules.
Disadvantage: Major design flaws will only be found at the end when the top modules are tested.
Sandwich Testing
Sandwich testing, is also known as hybrid testing, it is a combination of the top-down and bottom-up approach in which you test the modules in the middle of the module hierarchy first followed by the other modules.
In our example, M-2, M-3 and M-4 will be tested first followed by the remaining modules.
Advantage: A good compromise for large projects.
Disadvantage: Difficult to design and write.
Advantages of Integration Testing
- More confidence in code than unit testing.
- Insurance against bad unit test cases.
- Exposes gaps and contradictions in the design document.
- Better localization of defects than system level testing.
- Can be automated and integrated into daily builds.
- Skill level of the person writing the test cases need not be high.
- Code coverage is higher than unit test cases.
Disadvantages of Integration Testing
- Requires people with knowledge of the programming language in which the software is being developed.
- Person designing test cases must have some level detective-like talent to create test cases that actually add value.
- People must also know how to integrate their test cases with the build system.
- Takes time to write and maintain.