Previously we were talking about the most important kind of tests for developers, unit tests. There is one more kind of tests that developers should write, integration tests. I’ll describe what Integration Tests are and why you would want to write them, finally we’ll compare them to Unit Tests. After that post you’ll know when to choose which type of tests.
What is Integration Test?
Having definition from previous post. Integration tests are used to test integration between two or more components. That means we’re going to use dependencies while running test. We can’t isolate them, because we want to know how chosen components work with each others. Everything else is similar to unit tests. That’s why I said that developers should write integration tests as well.
What are ITs for?
First of all, integration tests are for something completely different than unit test. You may use them to check if every part of your application can work with rest. So while in unit tests you would fake response from database to make sure that errors in database won’t break functionality tests. In integration tests you would use living database to make sure that database can talk to your services.
If you can’t test something with unit test, you can be sure that with integration test it is possible. That’s because integration test works almost like manual test, but instead of clicking every time, you’ll create test that will call whole application flow.
Why shouldn’t I write only integration tests then?
There is approach to write only integration tests, because as I said you can test everything with it. There are problems thou. First of all, integration tests use whole environment that means they can send http requests, store data on database, save data to files. All of these operation are considered as slow.
So running multiple times test that will take 10 seconds to finish is problematic. What if you would like to run more tests? That would take 1 minute, I hope you know where I’m going. Developer would probably run those tests once, at the end of his work. On the other hand, running dozens of unit tests will take milliseconds.
Another thing, we have to clean up after integration tests. As I said before they would use your whole code. So if you store something on database, integration test will store its result there as well, there will be mess in no time, or even worse your test will fail, because something already exist, due to previous test run that left its results.
Well, why should we even bother with IT then?
Because we’re lazy. We want to have automatic way to check if our application works. It is perfect job for integration tests.
Integration tests are slower than unit tests, so what? We will run them once at night and another time when developer merge his changes with develop branch. It will happen in the background, while others will do code review.
Additionally you don’t need to test across whole application with one test. You can test only 2 or 3 layers and then fake responses at some point. For example test would call Web API via http, but API wouldn’t call database for data, it would have faked data so no change on database couldn’t break this test. In this scenario we want to check if client can talk with WebAPI. We don’t care about how API will get data, we just want to take request and give response.
Then second test would omit http request and run method straight from controller, but controller would use living database. In this scenario we don’t care why controller wants to access data, we tested that before. This time we want to know if controller can load anything from database.
Test Pyramid
Integration tests are more expansive and will take more time to maintain. That only means you can’t test everything with integration tests. There is scheme called Test Pyramid, it shows perfectly what I mean.
You should test as much as you can with unit tests, there should be far more unit tests than rest of tests gathered together. Then integration tests, less than unit tests, that would check only specific scenarios and happy paths, finally GUI tests, the most fragile. Your application doesn’t need too much of those, because they are the hardest to maintain, even minor change can break all of them, because they’ll use application GUI to work. At the peak, there are manual tests.
Our goal is to eliminate manual testing, it’s almost impossible, because there are place that are too expansive to create test for, but one person can check it in matter of few minutes. You should remember just don’t depend on manual testing, it is straight way to destroy project.
Outro
Now you can see the difference. Cheap, quick unit tests that can check logic in your code. Slower, more expansive integration tests that can also check your logic, but what’s more important check how your code would work with other parts.
At start I highly recommend to talk to testers in your team. Learn from them which type of tests they would use and always ask why, only then you can understand their thinking. At some point you’ll know as well, which test you should write next.