如何使用多个 docker 设置 Gitlab CI E2E 测试

Posted

技术标签:

【中文标题】如何使用多个 docker 设置 Gitlab CI E2E 测试【英文标题】:How to setup Gitlab CI E2E tests using Multiple dockers 【发布时间】:2021-05-10 06:03:09 【问题描述】:

我对使用 Gitlab CI 的自动化测试有点迷茫。我希望我能解释我的问题,以便有人可以帮助我。我会先尝试解释情况,然后我会尝试提出一个问题(这比听起来更难)

情况

架构

    React 前端与 Jest 单元测试和 Cypress e2e 测试 Django API 服务器 1 包括 Postgres 数据库和测试 带有 MongoDB 数据库的 Django API 服务器 2(与其他 API 通信

Gitlab

对于这 2 个 API,有一个 Docker 和一个 docker-compose 文件。这些工作正常并且设置正确。

我们将 GitLab 用于 CI/CD,我们按此顺序有以下阶段:

    build: 其中 1、2 和 3 的 docker 是单独构建并推送到 private-registry 测试: 单元测试和 e2e 测试(应该)在哪里运行 发布: docker 镜像的发布位置 部署: docker 镜像的部署位置

目标

我想设置 GitLab CI 以便它运行 cypress 测试。但为此,需要所有构建 docker。目前,在执行端到端测试时,我无法同时使用所有 docker。

问题

我真的不明白我将如何实现这一目标。

我可以使用构建阶段构建的 docker 进行 e2e 测试吗?有人可以举例说明如何实现吗? (通过将构建 docker 容器作为服务运行?) 我需要一个包含所有 docker 和数据库的 Docker-compose 文件吗? 我还需要dind吗?

我希望有人可以就如何实现这一目标给我一些建议。举个例子会更好,但我不知道是否有人愿意这样做。

感谢您抽出宝贵时间阅读!

(如果需要) API 服务器示例 1

build-api:
  image: docker:19
  stage: build
  services:
    - docker:19-dind
  script:
    cd api
    docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    docker pull $IMAGE_TAG_API:latest || true
    docker build -f ./Dockerfile --cache-from $IMAGE_TAG_API:latest --tag $IMAGE_TAG_API:$CI_COMMIT_SHA .
    docker push $IMAGE_TAG_API:$CI_COMMIT_SHA

test-api:
  image: docker:19
  stage: test
  services:
    - postgres:12.2-alpine
    - docker:19-dind
  variables:
    DB_NAME: project_ci_test
    POSTGRES_HOST_AUTH_METHOD: trust
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker pull $IMAGE_TAG_API:$CI_COMMIT_SHA
    - docker run $IMAGE_TAG_API:$CI_COMMIT_SHA sh -c "python manage.py test"
  after_script:
    - echo "Pytest tests complete"
  coverage: "/TOTAL.+ ([0-9]1,3%)/"

release-api-staging:
  image: docker:19
  stage: release
  services:
    - docker:19-dind
  only:
    refs: [ master ]
    changes: [ ".gitlab-ci.yml", "api/**/*" ]
  environment:
    name: staging
  script:
    - docker pull $IMAGE_TAG_API:$CI_COMMIT_SHA
    - docker tag $IMAGE_TAG_API:$CI_COMMIT_SHA $IMAGE_TAG_API:latest
    - docker push $IMAGE_TAG_API:latest

【问题讨论】:

我发表了一篇关于在 GitLab 中使用微服务进行端到端测试的文章,我猜它会有所帮助:medium.com/@datails/… 【参考方案1】:

答案有点晚了,但我仍然会尝试 explain the approach 简要介绍其他有相同问题的开发人员。我还创建了一个example project,在 GitLab 中包含 3 个微服务,其中服务器 A 运行端到端测试并依赖于服务器 B 和服务器 C。

当 e2e 测试全栈应用程序时,您必须:

模拟微服务的所有响应 针对已部署的环境进行测试; 或在管道中临时启动环境

如您所述,您希望在管道中临时启动环境。应采取以下步骤:

    在 GitLab 的私有注册表中将所有后端部署为 docker 镜像; 在 1 个工作中模仿您的 docker-compose.yml 服务; 将这些点连接在一起。

在 GitLab 私有注册表中将后端部署为 docker 映像

首先你必须在 GitLab 的私有注册表中发布你的 docker 镜像。您这样做是因为您现在可以在另一项工作中重复使用这些图像。对于这种方法,您需要docker:dind。发布到 gitlab 上的私有注册表的简单示例作业如下所示:

before_script:
  - echo -n $CI_JOB_TOKEN | docker login -u gitlab-ci-token --password-stdin $CI_REGISTRY

publish:image:docker:
  stage: publish
  image: docker
  services:
    - name: docker:dind
      alias: docker
  variables:
    CI_DOCKER_NAME: $CI_REGISTRY_IMAGE/my-docker-image
  script:
    - docker pull $CI_REGISTRY_IMAGE || true
    - docker build --pull --cache-from $CI_REGISTRY_IMAGE --tag $CI_DOCKER_NAME --file Dockerfile .
    - docker push $CI_DOCKER_NAME
  only:
    - master

要查看真实示例,我有一个公开可用的example project。

在管道中的 1 个作业中模仿您的 docker-compose.yml 服务

将所有后端 docker 化并在私有注册表上发布图像后,您就可以开始使用 GitLab 作业来模仿您的 docker-compose.yml。一个基本的例子:

test:e2e:
   image: ubuntu:20.04
   stage: test
   services:
      - name: postgres:12-alpine
        alias: postgress
      - name: mongo
        alias: mongo
      # my backend image
      - name: registry.gitlab.com/[MY_GROUP]/my-docker-image
        alias: server
   script:
      - curl http://server:3000 # expecting server exposes on port 3000, this should work
      - curl http://mongo:270117 # should work
      - curl http://postgress:5432 # should work!

运行测试

现在一切都在 GitLab 的单个作业中运行,您可以简单地以分离模式启动前端并运行 cypress 来测试它。示例:

 script:
   - npm run start & # start in detached mode
   - wait-on http://localhost:8080 # see: https://www.npmjs.com/package/wait-on
   - cypress run # make sure cypress is available as well

结论

您的docker-compose.yml 不打算在管道中运行。模仿它而不是使用GitLab services。将所有后端 Dockerize 并存储在 GitLab's private registry 中。启动管道中的所有服务并运行测试。

【讨论】:

【参考方案2】:

这篇文章可能会有所启发。 https://jessie.codes/article/running-cypress-gitlab-ci/ 本质上,您制作了两个 docker composer,一个用于 Cypress 测试,一个用于您要测试的项目。这解决了图像能够访问节点和 docker 的问题。

【讨论】:

以上是关于如何使用多个 docker 设置 Gitlab CI E2E 测试的主要内容,如果未能解决你的问题,请参考以下文章

设置 GitLab CI/CD 以将多个存储库部署到 DigitalOcean Droplet 上的 Docker 容器

如何设置GitLab +运行器来缓存Docker层

使用多个 docker 守护进程运行 gitlab-runner

使用 gitlab-ci 构建多个 Docker 镜像

如何正确设置环境变量 Gitlab CI/CD 和 Docker

使用 Docker-Composer 设置 GItlab 时出错