unit-testing - 在 docker build 中缓存 "go get"

标签 unit-testing go docker docker-compose

我想将我的 golang 单元测试封装在一个 docker-compose 脚本中,因为它依赖于几个外部服务。我的应用程序有很多依赖项,所以需要一段时间才能go get

我怎样才能以允许 docker 容器构建的方式缓存包,而不必每次我想测试时都下载所有依赖项?

我的 Dockerfile:

FROM golang:1.7

CMD ["go", "test", "-v"]

RUN mkdir -p /go/src/app
WORKDIR /go/src/app

COPY . /go/src/app
RUN go-wrapper download
RUN go-wrapper install

每次我想运行单元测试时,我都会在以下脚本上运行 docker-compose up --build backend-test:

version: '2'
services:
  ...
  backend-test:
    build:
      context: .
      dockerfile: Dockerfile
    image: backend-test
    depends_on:
      ...

但现在每次我想运行测试时都会调用 go-wrapper download 并且需要很长时间才能完成。

解决方案?提前致谢!

最佳答案

我个人使用 govendor .它根据 golang vendor 约定将您的依赖项保存在项目内的 vendor 目录中。这仍然需要在构建时复制到您的 docker 镜像中。

但是有很好的理由不 vendor 。例如,当您构建 pkg 时,您不应该 vendor 。当您有不同的 pkg 使用不同版本的依赖项时,事情会变得一团糟。这只能通过销售可执行文件来解决。

因此,如果您有充分的理由不 vendor ,您可以分开几个步骤。 将它们按正确的顺序排列会加快速度。

您可以使用一些 go get 命令创建一个 shell 脚本 (get.sh) 来获取依赖项。 (你可以将它们放在你的 Dockerfile 中,但它们有行限制)

go get github.com/golang/protobuf/proto
go get github.com/pborman/uuid
go get golang.org/x/net/context
go get golang.org/x/net/http2
go get golang.org/x/net/http2/hpack

然后在您的 Dockerfile 中,您首先复制并执行 shell 脚本。 每次更新 get.sh 时,它都会完全重建。它仍然运行 got get ./... 以确保所有依赖项都存在。但是,如果所有内容都添加到 get.sh 脚本中,您将获得不错的速度提升。

FROM golang:1.6

RUN mkdir -p /go/src/app

COPY get.sh /go/src/app

WORKDIR /go/src/app

RUN bash get.sh

COPY . /go/src/app

RUN go get ./...

CMD go test -v

一般的想法是,您经常更改 Dockerfile 中较低的内容,而顶部的内容则非常稳定。即使您必须添加另一个或两个命令。 Docker 将逐行执行,直到找到需要重建的内容,然后也会执行之后的每一行。

关于unit-testing - 在 docker build 中缓存 "go get",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39278756/

相关文章:

go - 如何检查接口(interface)是 golang 中的 map[string]string

unit-testing - 执行 TDD 时要模拟哪些对象

JQuery 模拟

c++ - C++ 中的单元测试

python - 模块导入错误,如何刷新Ipython session ?

docker - 使用不同 docker-compose 配置构建的容器之间的可见性

docker - Windows docker "docker ps"不工作

java - 模拟删除方法

go - 如何限制 Go 中实现的 HTTP 服务器的连接数?

go - 即使进程结束也缓存或保留一个值