Go: Docker for Golang application tests

Kanan Rahimov
Nov 3 · 3 min read
Golang’s Gopher with Docker’s Whale :)

Docker widely used in the development environment, and one of the usages is testing.

This article will focus on two different usages of Docker for Golang tests:

1. Use Docker image to test and build your application

2. Use Go package to set up and run Docker images programmatically

During this article, we will use MongoCLI open-source repository as an example. Consider checking it out.

https://github.com/KenanBek/mongocli

Docker image for your application.

Having a Docker image for your application is quite straightforward and commonly used approach. It gives you isolation from your local machine and can be run anywhere where you have Docker installed. We can apply the same technics to any other programming language. Also, we can have one image for the back-end and another for the front-end.

Here is an example Docker image (also taken from mongocli):

FROM golang:latest
RUN mkdir /app
ADD . /app/
WORKDIR /app
RUN go test -v ./...
RUN go build -o mongocli mongocli.go
RUN touch ~/mongocli.yml
RUN echo -e "Server: db\nPort: 27017" > ~/mongocli.yml
RUN touch mongocli.yml
ENV PATH="/app:${PATH}"

Here we use an official Go image as a base: golang:latest. Then we set-up our environment and run tests. Once all tests passed, we build our application and save it as the mongocli executable file.

We can build and run this image using the following command:

docker build -f Dockerfile -t mongocli:latest .
docker run mongocli:latest

Also, we can execute our mongocli application from within Docker container:

docker run mongocli:latest mongocli help

Go package dockertest to manage containers during the tests

For this approach, we will need an external package. There are a few of Go packages for this purpose. In this article, I will focus on dockertest:

Let’s start with a code:

Go and MongoDB integration tests using Dockertest

As you can see, we have TestMain as an entry point for our tests. In this function, we initialize an instance of dockertest’s Pool and try to spawn up MongoDB container.

If the initialization of the container went successful, we get the port number for MongoDB and create an instance of our tested object — mc (line 38) — and run test command — Ping (line 39).

Once we have successful preparation, we keep a global instance of the needed object (mc, line 13) and pass execution flow to a required test.


Summary

Both approaches work well. But there is one mention-worthy point. Theoretically, if with case one, you can have a bunch of tests and call them unit tests, however, in case two, it will be very questionable if you can call the same tests unit tests when you have an external dependency like, for example, MongoDB. Details of this statement are probably for the next article. Until then, happy coding!

Kanan Rahimov

Written by

Software Engineer. Author @CoderVlogger. Check https://kenanbek.github.io/ for more posts and updates.

Engineering Hub

The best way to learn something is to teach it. That’s why We, as a Team of Engineers, decided to establish Engineering Hub. Our goal is to share with our readers what We learn and to hone our skills. We are sure You will endeavor from this idea as much as We will.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade