Docker 单元测试:如何测试 Dockerfile(2020 指南)

2025-05-24

Docker 单元测试:如何测试 Dockerfile(2020 指南)

你知道你应该测试一切......

不是吗?

好吧,在开发新的 Dockerfile 时,为 Docker 编写单元测试应该成为你日常工作的一部分。它可以为你节省大量运行 Docker 镜像的时间,让你无需费力找出问题所在,还能大大减少你对重建和更新容器的恐惧(如果你仍然不相信我关于测试的论述,请阅读James Shore的这篇文章)。

在本指南中,您将了解:哪些工具可以帮助您测试 Dockerfile,如何为 Docker 编写单元测试以及如何在持续集成管道中自动化它。

Docker容器结构

我能推荐的编写 Docker 单元测试的最佳工具是容器结构测试框架。
这个由 Google 开发的框架可以让你非常轻松地测试容器镜像的结构。

如何安装

如果您使用 Linux,请运行:

curl -LO https://storage.googleapis.com/container-structure-test/latest/container-structure-test-linux-amd64 && chmod +x container-structure-test-linux-amd64 && sudo mv container-structure-test-linux-amd64 /usr/local/bin/container-structure-test
Enter fullscreen mode Exit fullscreen mode

测试选项

集装箱结构测试提供4种类型的测试:

  • 命令测试:在图像中执行命令并检查输出
  • 文件存在测试:检查文件是否存在于图像中
  • 文件内容测试:检查文件的内容
  • 元数据测试:检查容器元数据是否正确

如何编写docker单元测试

您所需要的只是一个 Dockerfile 和一个.yaml包含.json测试用例的文件。

编写你的第一个 Docker 单元测试

对于此示例,我们将使用以下 Dockerfile 作为可在 CI 中使用Bazel构建代码的图像。

FROM ubuntu:bionic

RUN apt-get update \
  && apt-get install -y curl gnupg \
  && curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg \
  && mv bazel.gpg /etc/apt/trusted.gpg.d/ \
  && echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" > /etc/apt/sources.list.d/bazel.list \
  && apt-get update \
  && apt-get install -y bazel \
  && rm -rf /var/lib/apt/lists/*

RUN groupadd -g 1000 user \
  && useradd -d /home/user -m -u 1000 -g 1000 user \
  && chown -R user:user /home/user \
  && mkdir -p /bazel/cache \
  && chown -R user:user /bazel

RUN echo "build --repository_cache=/bazel/cache">/home/user/.bazelrc
Enter fullscreen mode Exit fullscreen mode

并且可以用以下方式构建:

docker build -t docker-unit-test .
Enter fullscreen mode Exit fullscreen mode

现在我们有一个以 root 身份设置的 Docker 镜像,但在 CI 上,我们希望尽可能地模拟开发人员构建环境,为此,我们将以非 root 用户身份运行构建。

可能出现什么问题?

事实上有很多事情!

用户有自己的构建配置文件吗?或者缓存文件夹?好吧,你可以在将 Docker 镜像部署到任何地方之前检查所有这些。

让我们创建unit-test.yaml并测试它!

schemaVersion: '2.0.0'
fileExistenceTests:
  - name: 'Check bazel cache folder'
    path: '/bazel/cache'
    shouldExist: true
    uid: 1000
    gid: 1000
    isExecutableBy: 'group'
fileContentTests:
  - name: 'Cache folder config'
    path: '/home/user/.bazelrc'
    expectedContents: ['.*build --repository_cache=/bazel/cache.*']
Enter fullscreen mode Exit fullscreen mode

第一个测试Check bazel cache folder将检查缓存文件夹是否存在,以及是否由非 root 用户拥有。第二个测试Cache folder config将检查 Bazel 构建配置文件内容是否符合预期。

一切设置完毕,我们可以通过这种方式运行测试:

$ container-structure-test test --image docker-unit-test --config unit-test.yaml

=======================================
====== Test file: unit-test.yaml ======
=======================================
=== RUN: File Content Test: cache folder config
--- PASS
duration: 0s
=== RUN: File Existence Test: Check bazel cache folder
--- PASS
duration: 0s

=======================================
=============== RESULTS ===============
=======================================
Passes:      2
Failures:    0
Duration:    0s
Total tests: 2

PASS
Enter fullscreen mode Exit fullscreen mode

这个框架对于在发布 Docker 镜像之前对其进行测试非常有用,它快速且易于使用。

自动化 Docker 容器测试

好的,现在我们已经准备好 Dockerfile 和测试,是时候自动化测试过程了!

在这个例子中,我假设你有一个Ansible流水线,用于在持续集成中构建、标记和推送 Docker 镜像。我们将为该流水线创建一个新任务来执行 Docker 单元测试。

- name: unit test Docker Image
  shell: |
    container-structure-test test --image {{ docker_image }} --config {{ test_file }}
    if $?
    then
      echo "Test Failed"
      exit 1
    else
      echo "Test Succeeded"
      exit 0
    fi
Enter fullscreen mode Exit fullscreen mode

就是这个!

通过 Twitter @gasparevitta联系我告诉我您的想法!

我希望您发现它很有用,并且从现在开始测试您的 Dockerfile。

您可以在Github上找到代码片段

本文最初发表在我的博客上。如果你喜欢这篇文章,并且想阅读其他类似的文章,欢迎访问我的博客!

文章来源:https://dev.to/gasparev/docker-unit-test-how-to-test-a-dockerfile-guide-2020-435d
PREV
构建稳固的 CI/CD 管道:综合指南
NEXT
将现代 JavaScript 引入库