Integration Testing with Golang (Test Containers)

Integration Testing is the phase in software testing in which individual software modules are combined and tested as a group. Container Testing is on the other hand allows you to test your dockerized application end-to-end with 3rd party tools as if were in the production environment and without any dependencies.

So what are the advantages and how we can implement it?

When someone tested the nitrogen filled tire with a lighter… —

What are the advantages?

Containers have multiple benefits for us and our applications. Less overhead, portability, more consistent operation and efficiency etc. In addition to all these, I think the most useful feature for our application is that it allows us to run the applications (db etc.) that we have developed with a single command, even if they are not installed on our computer.

So what is its relationship with integration tests? While testing the application we wrote in integration tests from end to end we can create other applications (db etc.) that the current application is dependent on, test it as if it were in a live environment and then delete them all. This allows us to run our tests as if our application was live with mock data.

How we can implement it?

I created a web application that has 2 endpoints as below;


And let’s start writing tests for these endpoints. There are 2 applications that our application is dependent on; PostgreSql for storage and RabbitMq for message broker. For this reason, we first write and implement the necessary structs and interfaces to create, use and delete the containers we need.

The implementation for PostgreSql is as follows;


Here I used ory’s dockertest package to manage the containers. If we wanted, we could write native with golang, but this package is quite enough.

Then I created a new file called controller_integration_test.go into the usercontroller package. I usually use testify while writing my tests, I recommend it.


Now we create the necessary instances before our tests run. Because these instances will be used in all tests.


Then I start test writing for user creation. The flow here is as follows. When the user creation request comes to the related endpoint, this user is created in the PostgreSql database and the Domain Event is threw to RabbitMq. Here if the flow is successful, I consume the event and check if it is really the correct message.

Here, you can monitor your tests while running and in Debug mode by connecting to applications if you want.

To run all tests;

$ go test -v ./...

And the result!

Result of tests

I write when I learn, I learn as I write. I may have made mistakes in many places because I am just a human. I would be glad if you correct it when you see any mistakes.

You can access the source code from here.
Thank you for your interest. See you in the next post :)

Follow me;

I don’t know what’s happening here? | software engineer @trendyol