This article explains how the main Go unit tests in Docker, depending Docker and Go Modules.
Why Docker
We often need to configure before Jenkins Docker on a different server version and configuration Go GOPATH for each project, poor isolation between projects, the problem underlying library version conflicts often arise.
With Docker, we can run the unit tests in different containers, this test is not confined to a different project, or even different branches of the same project.
He has improved so much on the test isolation and concurrency testing project, and after the end of the test, environmental clean-up is also much simpler.
Why Go Modules
Go Modules as the official default package management tool, basically solved the problem of package management Go longstanding, it brings a lot of benefits for our project management:
- Automatically parse and add dependencies
- Signature verification
- Dependence cache
- Support relative path dependence
- Support rely on a key package, easy to run the program in the offline environment
Practical examples
Let's look at a simple example, from Gin Testing Example, the project directory structure:
$ tree .
.
├── go.mod
├── go.sum
├── main.go
└── main_test.go
0 directories, 4 files
main.go content:
package main
func setupRouter() *gin.Engine {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.String(200, "pong")
})
return r
}
func main() {
r := setupRouter()
r.Run(":8080")
}
main_test.go content:
package main
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPingRoute(t *testing.T) {
router := setupRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/ping", nil)
router.ServeHTTP(w, req)
assert.Equal(t, 200, w.Code)
assert.Equal(t, "pong", w.Body.String())
}
First, try to execute go test in the host. / ..., through testing, let's think of ways to be tested in the Docker.
Docker test run
Step 1: The dependence of the packaged items to facilitate run unit tests the network environment without Docker
go mod vendor
At this point all the dependencies are packaged in the project root directory vendor the following:
$ tree .
.
├── go.mod
├── go.sum
├── main.go
├── main_test.go
└── vendor
├── github.com
│ ├── davecgh
│ │ └── go-spew
│ │ ├── LICENSE
│ │ └── spew
│ │ ├── bypass.go
│ │ ├── bypasssafe.go
│ │ ├── common.go
Step 2: Production image Go Docker
Go because we only need a standard environment, it is possible to use the official standard mirror, for example golang: 1.12.1.
If you have special needs, you can customize your own Go mirroring, for example, custom boot commands, add the database dependence:
- Dockerfile:
FROM ubuntu
RUN apt-get update && apt-get install -y libssl1.0.0 libssl-dev gcc
RUN mkdir -p /data/db /opt/go/ /opt/gopath
# go1.xx.x.linux-amd64.tar.gz 解压缩后为 go
ADD go /opt/go
RUN cp /opt/go/bin/* /usr/local/bin/
ENV GOROOT=/opt/go GOPATH=/opt/gopath
WORKDIR /ws
CMD GOPROXY=off go test -mod=vendor ./...
- Execution docker build:
docker build . -t gotesting:v0.0.1
Step 3: Run Golang the test Docker
- Use golang: 1.12.1:
$ docker run --volume=$(pwd):/ws \
--workdir=/ws golang:1.12.1 \
/bin/bash -c "GOPROXY=off go test -mod=vendor ./..."
ok github.com/songjiayang/gin-test 0.011s
- Using custom images gotesting: v0.0.1:
docker run --volume=$(pwd):/ws gotesting:v0.0.1 ok github.com/songjiayang/gin-test 0.014s
You can see two ways to run the unit tests in Docker Go in, custom mirrors can specify the default run command makes the operation more simple, the meaning of the above command is:
- -volume = $ (pwd): / ws: is mapped to the project root / ws directory Docker container.
- -workdir = / ws: Specifies the working directory to run container / ws, that is mapping out the project root directory.
- / Bin / bash -c "GOPROXY = off go test -mod = vendor ./...": indicates the Go Docker unit testing to offline, vendor mode.
do better
So far, we have mastered how to run unit tests in Docker Go in. Of course, we can do better, can run standard output Docker Jenkins and natural integration, automatic test project.
Author: Sonja ocean