docker 运行运行容器
99% of the time, I can simply unit test my project locally without any issues. However, occasionally I run into a situation where I need some 3rd party software installed for the application to work properly, which I just don’t want to install on my laptop. You may also not be able to install software on your laptop/PC due to security rules of your organization. This usually results in incomplete unit tests, as I can’t fully test the functionality of the code dependent on the 3rd party software. Luckily, we can utilize Docker for this very scenario and get complete unit test coverage.
99%的时间,我可以简单地在本地对项目进行单元测试,而不会出现任何问题。 但是,偶尔我会遇到这样的情况,我需要安装一些第三方软件才能使该应用程序正常运行,而我只是不想将其安装在笔记本电脑上。 由于组织的安全规则,您可能也无法在笔记本电脑/ PC上安装软件。 这通常会导致单元测试不完整,因为我无法完全测试依赖于第三方软件的代码的功能。 幸运的是,我们可以在这种情况下利用Docker并获得完整的单元测试范围。
Before we get started, this post can absolutely apply to any language where you have a need to run tests inside a Docker container. However, for this post, we’ll be looking at a Go project where I found myself in need of this very thing.
在我们开始之前,本文绝对适用于您需要在Docker容器中运行测试的任何语言。 但是,对于本文,我们将看一个Go项目 ,我发现自己需要这个东西。
设置 (The Setup)
For this project, I was playing with Go’s templating engine via thehttp/templatepackage. I’m taking the output of that templating and saving it as an HTML file, then converting that to a PDF. To handle the PDF conversion, I’m using an open-source command-line tool called wkhtmltopdf. This is a very simple tool that can run headless which is exactly what I need. This is a REST API, using the Goji framework, which is meant to run in a Docker container. Getting wkhtmltopdf installed is no problem, as you can see in my Dockerfile.
对于这个项目,我正在通过http/template包使用Go的模板引擎。 我正在获取该模板的输出,并将其保存为HTML文件,然后将其转换为PDF。 为了处理PDF转换,我使用了名为wkhtmltopdf的开源命令行工具。 这是一个非常简单的工具,可以无头运行,这正是我所需要的。 这是一个使用Goji框架的REST API,该框架旨在在Docker容器中运行。 如您在我的Dockerfile中所见,安装wkhtmltopdf没问题。
FROM golang:latest as BUILDWORKDIR builddirCOPY . .RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o go-goji-templating-pdf-generation-apiFROM alpine:3.12.0RUN apk update && \ apk add xvfb ttf-freefont fontconfig wkhtmltopdf ghostscriptCOPY --from=BUILD ./go/builddir/go-goji-templating-pdf-generation-api .ENTRYPOINT ["./go-goji-templating-pdf-generation-api"]
This is pretty straight-forward but let’s unpack it. First, we’re performing a multi-stage build, using a Golang Docker image to perform the actual build. Next, we use an Alpine container to keep the size as small as possible and install some dependencies, one of which is wkhtmltopdf. The other packages are needed for things like CSS rendering and compression. Finally, we copy the build from the previous step and we’re done.
这很简单,但是让我们打开它的包装。 首先,我们执行一个多阶段构建,使用Golang Docker映像执行实际构建。 接下来,我们使用Alpine容器使尺寸保持尽可能小并安装一些依赖项,其中之一是wkhtmltopdf。 其他包是CSS渲染和压缩之类的。 最后,我们复制上一步的构建,然后完成。
Invoking wkhtmltopdf is simple enough using the os/execpackage. In this function, we accept a path to where the HTML file exists, as well as the PDF to where we want the PDF to be output.
使用os/exec软件包调用wkhtmltopdf非常简单。 在此函数中,我们接受HTML文件存在的路径,以及我们希望将PDF输出到的PDF。
func ConvertHTMLtoPDF(htmlFilePath string, pdfFilePath string) error { args := []string{htmlFilePath, pdfFilePath} cmd := exec.Command("wkhtmltopdf", args...) err := cmd.Run() if err != nil { log.Print(err) return err } return nil}
This is a nice simple function, that is very easy to test. Unless you don’t have wkhtmltopdf installed on the machine running the tests! At this point, I have just one option, run a negative test by calling the function, and inspecting the error. You will get back an error of “exec: “wkhtmltopdf”: executable file not found in $PATH”. While this bumps up your lines of coverage metric, it's not really testing your code.
这是一个很好的简单函数,非常易于测试。 除非您没有在运行测试的计算机上安装wkhtmltopdf! 此时,我只有一个选择,通过调用函数并检查错误来运行否定测试。 您将返回错误“ exec:“ wkhtmltopdf”:在$ PATH中找不到可执行文件”。 虽然这提高了覆盖率指标的范围,但实际上并没有测试您的代码。
码头救援 (Docker to the Rescue)
To run our unit tests in Docker we need to create a new container with wkhtmltopdf installed along with our uncompiled code. This Dockerfile looks like the following.
为了在Docker中运行单元测试,我们需要创建一个新容器,其中安装了wkhtmltopdf以及未编译的代码。 该Dockerfile如下所示。
FROM golang:latest as BUILDRUN apt-get update && \ apt-get install -y xvfb wkhtmltopdf ghostscriptWORKDIR testdirCOPY . .ENTRYPOINT ["go", "test", "-v", "./...", "-coverprofile", "cover.out"]
This Dockerfile is much more streamlined than before. We can use the Golang base image as we’re less concerned with size for running tests. Also, we can install fewer packages, as for unit tests I don’t care about the CSS rendering, just PDF conversion. Finally, we make the entrypoint our go test command, with a coverage report for good measure. We need this file Dockerfile.testas we only use this one for running tests.
这个Dockerfile比以前更加简化了。 我们可以使用Golang基本映像,因为我们不太关心运行测试的大小。 另外,我们可以安装更少的软件包,至于单元测试,我不在乎CSS渲染,而在乎PDF转换。 最后,我们将入口点设置为go测试命令,并带有覆盖率报告,以作好衡量。 我们需要此文件Dockerfile.test因为我们仅将其用于运行测试。
We can now build this container with the following command:
现在,我们可以使用以下命令构建此容器:
docker build -t github.com/atkinsonbg/go-goji-templating-pdf-generation/api/tests:latest -f Dockerfile.test .
And we can run the container with the following command:
我们可以使用以下命令运行容器:
docker run github.com/atkinsonbg/go-goji-templating-pdf-generation/api/tests:latest
Running this command produces an output of all our tests in the terminal and we can successfully test wkhtmltopdf without installing it locally! This is great on so many levels. If you’re working on a team of developers, you don’t have to worry about local setup. If your organization won’t allow 3rd party software to be installed locally, no worries. If you’re like me, and just prefer a pristine laptop, then you’re golden. If your CI/CD pipeline supports Docker containers, you can even now test this via your pipeline! Life is good.
运行此命令将在终端中生成我们所有测试的输出,并且我们可以成功测试wkhtmltopdf而不在本地安装它! 在许多级别上这都很棒。 如果您正在开发团队中工作,则不必担心本地设置。 如果您的组织不允许在本地安装第三方软件,则无需担心。 如果您像我一样,并且只喜欢一台质朴的笔记本电脑,那么您就是黄金。 如果您的CI / CD管道支持Docker容器,您现在甚至可以通过管道对其进行测试! 生活很好。
But wait, what about our coverage report! We’re running our tests successfully, but our coverage report is in the container! We need that back out so we can have a record of our test coverage. Not a problem, all we need to do is mount a volume to get the coverage report out. We can do this by updating our run command with a volume mount:
但是,等等,我们的覆盖率报告呢! 我们已经成功运行了测试,但是我们的覆盖率报告在容器中! 我们需要回退,以便可以记录我们的测试覆盖率。 没问题,我们要做的就是挂载卷以输出覆盖率报告。 我们可以通过使用卷挂载更新运行命令来做到这一点:
docker run -v ${PWD}:/go/testdir github.com/atkinsonbg/go-goji-templating-pdf-generation/api/tests:latest
With this new command, we’re simply mounting our current working directory to the work directory we created in the Dockerfile.test file. Just in case you missed it, we’re operating in a Golang container and using go mods, so we have to be in a working directory that is not root. As such, our mount needs to reference the root “go” folder to work properly.
使用此新命令,我们只需将当前工作目录挂载到我们在Dockerfile.test文件中创建的工作目录中。 万一您错过它,我们将在Golang容器中运行并使用go mods,因此我们必须位于非root用户的工作目录中。 因此,我们的挂载需要引用根目录“ go”文件夹才能正常工作。
Running this new command will drop the coverage report into our repo.
运行此新命令会将覆盖率报告放到我们的仓库中。
结语 (Wrapping Up)
Docker continues to be an essential part of my daily development. Even in this very simple example, you can see the power and flexibility it provides. As stated before, this is not directly tied to Go. If you have needs like this in any development project, Docker can solve it for you.
Docker仍然是我日常开发的重要组成部分。 即使在这个非常简单的示例中,您也可以看到它提供的功能和灵活性。 如前所述,这并不直接与Go绑定。 如果您在任何开发项目中都有这样的需求,Docker可以为您解决。
翻译自: https://levelup.gitconnected.com/running-go-unit-tests-inside-a-docker-container-a41ebfcfd854
docker 运行运行容器


所有评论(0)