Unit Test In Go With Docker

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

Guess you like

Origin blog.51cto.com/51reboot/2440255