DEV Community

Heitor Danilo
Heitor Danilo

Posted on

What is a Integration Test And How To Write One I

As a software developer, having your code merged into the production branch and undergoing the post-deployment phase can be one of the most anxiety-inducing stages. Fortunately, tests serve us well on this matter.

Tests typically verify that something returns the expected output for a given input. For example, a test for a function called sum would check if sum(x, y) == x + y. However, real-world scenarios often involve outputs that are much more complicated than a simple sum of two numbers.

What is a Integration Test?

According to Wikipedia, a integration testing is [...] the phase in software testing in which the whole software module is tested or if it consists of multiple software modules they are combined and then tested as a group. Often, this group includes software whose behavior is beyond our control. This complicates the process of obtaining expected outputs, as the availability or behavior of these external components may be unpredictable.

For instance, consider an API service that uses MongoDB to store data. An integration test could evaluate different aspects, including testing the data layer (CRUD operations) or examining the entire system through HTTP requests to the API, which interacts with MongoDB. In both scenarios, the goal is to test the combined functionality of the services. Initially, we verify the interaction solely with the database, before examining the system as a whole.

Looking into the first problem, one solution is to maintain a dedicated test branch on a cloud database or to launch a local Docker container before initiating our tests, thereby enabling connection to the test environment. Regarding the second issue, leveraging cloud infrastructure allows us to establish a staging server or set up a series of local containers, encompassing both the API and MongoDB components for thorough testing.

Both cloud-based and local solutions are important: while the cloud, coupled with CI/CD, can help us automate these tests, Docker enables us to test things locally, saving time and money.

However, complexity can quickly escalate. We might need to run multiple databases (and APIs) for parallel testing, or prepare extensive fixtures before executing any operation. Multiple developers might require access to CI/CD simultaneously or numerous tests may necessitate their own isolated environments. In the cloud, associated costs can escalate accordingly, while locally, our resources can quickly become insufficient.

Identifying cases

One of the most challenging aspects of writing integration tests is determining what exactly needs to be tested. The line between what constitutes a unit test and what constitutes an integration test can often be quite blurry.

For instance, consider an imaginary POST sent to /users, which can accept a JSON body structured as follows:

{
    "username": "string",
    "password": "string"
}
Enter fullscreen mode Exit fullscreen mode

In this schema, the password field is expected to contain at least one numerical digit. This criterion is evaluated by a function named evaluatePassword. Should the focus of the test be on unit testing this function, or should an integration test verify whether it has been invoked?

I believe both! Initially, we should write unit tests to verify each possible case for evaluatePassword. Subsequently, we should write an integration test to ensure the correct functioning of the overall system, verifying if the statuses are as expected for both cases (valid and invalid passwords). This validation must be performed for every possible exit status in the route.

For integrations where we lack control over implementation, such as database calls, we must test all scenarios covered. For example, if we have a getUser method responsible for handling both user existence and non-existence, we must test both functionalities.

Writing tests

At this point, you already know what an integration test is and how to identify one.

In the next part of this series, we will write a simple integration test using Go and Docker.

Top comments (0)