What’s Difference Between Unit Test and Integration Test

I have noticed there are many engineers who cannot distinguish between the unit test and integration test. Even though these two tests are as different as their names, we still cannot use them in the right place. This article helps you understand them and use them correctly.

In order to explain them better, I recommend this article, which introduces the dependency injection to the unit tests to achieve more testing coverage rate. I will leverage the example in it and dive into the integration test further. Before talking about the integration test, let’s take a quick look at the relationship between the unit test and the dependency injection.

Unit Test and Dependency Injection

Here comes a function, aka a unit, saveData.

As we have seen, we need to verify both the success case and failure case to achieve complete test coverage within the unit tests.

Therefore, we can leverage the dependency injection to prune the external dependency from a database.

Like the above examples, we fake the database objects and make sure our business logic is correct. The keyword is “business logic”. We verify the whole business logic in unit tests no matter what the database is. By using the dependency injection, we can easily verify the business logic and reach a high coverage rate.

Integration Test

Alright, we have already ensured the unit works without the database. Things are not likely to go so smoothly after the database is involved. Thus, we have to make some integration tests to verify the database works as our expectations.

We have already verified the units, therefore, we can only verify the database part, i.e "insert into mydatabase.mytable (data) value ('" + data +"')" as follows.

This example is not structured well, because we can apply the layered architecture to build an abstraction upon SQL query, called DAL (data access layer). Hence, we can have a cleaner interface to test the database instead of using raw SQL in a test case. Moreover, in Domain-Driven Development, there is a similar pattern, Repository, and it provides encapsulation for the database access. Those methods are able to provide convenience for writing integration tests.

Of course you can replace the dependency injection with other techniques like mocking. However, in my opinion, mocking will introduce much more implement efforts on writing the integration tests. By using the dependency injection, we will have an independent module/object/interface for the integration.

Conclusion

Why should we distinguish between the unit test and integration test? The reason is doing integration tests will take a lot of time, most of the time from the database access. Suppose an integration test case takes 100 ms, which is very fast for the database access, then it is hard for us to write thousands of test cases. In order to fully test a system, we always try to cover every decision in every function from every file, thus, controlling total time consumption is essential.

That is why Test Triangle shows the unit test at the bottom, and the integration test is up on it.

Let me summarize what is the main difference between unit tests and integration tests.

Unit tests are made for testing business logic; on the other hand, integration tests are for verifying the external dependencies.

With messing up the scenes, it will end up spending more effort and getting less results.

Originally published on Medium