Unit Test In Go With Docker

3719 ワード

この記事では、DockerとGo Modulesに依存して、DockerでGoユニットテストを行う方法について説明します.

なぜDocker?


Dockerの前にJenkinsサーバで異なるGoバージョンを構成する必要があり、プロジェクトごとにGOPATHを構成する必要があります.プロジェクト間の隔離性が悪く、ベースライブラリバージョンの競合の問題がよく発生します.
Dockerがあれば、異なるプロジェクトに限らず、同じプロジェクトの異なるブランチでも、異なるコンテナでユニットテストを実行できます.
そのため、テストの隔離性とプロジェクトのテストの同時性が大幅に向上し、テストが終わった後、環境のクリーンアップも簡単です.

なぜGo Modulesなのか


Go Modulesは、政府のデフォルトのパッケージ管理ツールとして、Goが長期にわたって存在するパッケージ管理の問題を基本的に解決し、私たちのプロジェクト管理に多くのメリットをもたらします.
  • 自動解析と依存
  • の追加
  • 署名検証
  • 依存キャッシュ
  • は、相対パス依存
  • をサポートする.
  • はワンタッチパッケージングをサポートし、オフライン環境でプログラム
  • を実行するのに便利である.

    実例


    次に、Gin Testing Exampleからの簡単な例を見てみましょう.プロジェクトディレクトリ構造は次のとおりです.
    $ tree .
    .
    ├── go.mod
    ├── go.sum
    ├── main.go
    └── main_test.go
    
    0 directories, 4 files
    
    

    main.goコンテンツ:
    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コンテンツ:
    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())
    }
    
    

    まずホストでgo test ./...を実行してみて、テストに合格しました.次はDockerでテストを行う方法を考えます.

    Docker実行テスト


    手順1:プロジェクト依存をパッケージ化し、Dockerのネットワークレス環境でユニットテストを容易に実行
    go mod vendor
    
    

    すべての依存は、プロジェクトルートディレクトリのvendorの下にパッケージされます.
    $ tree .
    .
    ├── go.mod
    ├── go.sum
    ├── main.go
    ├── main_test.go
    └── vendor
        ├── github.com
        │   ├── davecgh
        │   │   └── go-spew
        │   │       ├── LICENSE
        │   │       └── spew
        │   │           ├── bypass.go
        │   │           ├── bypasssafe.go
        │   │           ├── common.go
    
    

    手順2:Go Dockerミラーを作成する
    Goの標準環境しか必要ないので、golang:1.12.1などの公式の標準ミラーを使用できます.
    特別なニーズがある場合は、起動コマンドのカスタマイズ、データベース依存の追加など、独自のGoミラーをカスタマイズできます.
  • 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 ./...
    
    
  • docker buildを実行する:
  • docker build . -t gotesting:v0.0.1
    
    

    手順3:DockerでGolangテストを実行する
  • 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
    
    
  • カスタムミラーgotesting:v 0を使用する.0.1:
  • docker run --volume=$(pwd):/ws gotesting:v0.0.1
    ok      github.com/songjiayang/gin-test 0.014s
    
    

    どちらの方法でもDockerでGoユニットテストを実行できます.カスタムミラーでは、デフォルトの実行コマンドを指定して、操作を簡単にすることができます.上のコマンドの意味は次のとおりです.
  • –volume=$(pwd):/ws:Dockerコンテナの/wsディレクトリにプロジェクトルートディレクトリをマッピングします.
  • –workdir=/ws:コンテナ実行作業ディレクトリを/ws、すなわち外部プロジェクトルートディレクトリをマッピングすることを指定します.
  • /bin/bash-c「GOPROXY=off go test-mod=vendor./...」:Dockerでオフラインで、vendorモードでGoユニットテストを実行することを示します.

  • もっとよくやった


    これまでDockerでGoユニットテストを実行する方法を把握してきました.もちろん、Dockerが実行する標準出力はJenkinsと天然に統合され、プロジェクトの自動テストを実現することができます.作者:宋佳洋51 reboot K 8 s课程1.18日开课,详细WeChat;17812796384