首页 > 解决方案 > Pytest 不能在带有 Docker-Compose 的 Gitlab CI Docker 执行器中使用“docker-compose exec -T web_service pytest”运行

问题描述

我尝试使用 Gitlab CI 的主要原因是在部署之前自动化单元测试。我想要

  1. 构建我的 Docker 映像并将它们推送到我的映像存储库,然后
  2. 确保我所有的 pytest 单元测试都通过,最后
  3. 部署到我的生产服务器。

-T但是,如果我包含如下标志,我的 pytest 命令根本不会运行。它只是立即返回 0 和“成功”,这是不正确的,因为我在那里有一个失败的测试:

docker-compose exec -T web_service pytest /app/tests/ --junitxml=report.xml

在我的本地计算机上,我在没有-T标志的情况下运行测试,如下所示,它运行正确(并且测试按预期失败):

docker-compose exec web_service pytest /app/tests/ --junitxml=report.xml

但是如果我在 Gitlab CI 中这样做,the input device is not a TTY如果我省略了-T标志,我会得到错误。

这是我的一些“.gitlab-ci.yml”文件:

image:
  name: docker/compose:1.29.2
  # Override the entrypoint (important)
  entrypoint: [""]

# Must have this service
# Note: --privileged is required for Docker-in-Docker to function properly,
# but it should be used with care as it provides full access to the host environment
services:
  - docker:dind

stages:
  - build
  - test
  - deploy

variables:
  # DOCKER_HOST is essential
  DOCKER_HOST: tcp://docker:2375
  DOCKER_DRIVER: overlay2

before_script:
  # First test that gitlab-runner has access to Docker
  - docker --version
  # Set variable names
  - export IMAGE=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
  - export MY_IMAGE=$IMAGE:web_service
  # Install bash
  - apk add --no-cache bash
  # Add environment variables stored in GitLab, to .env file
  - chmod +x ./setup_env.sh
  - bash ./setup_env.sh
  # Login to the Gitlab registry and pull existing images to use as cache
  - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY

build:
  stage: build
  script:
    # Pull the image for the build cache, and continue even if this image download fails (it'll fail the very first time)
    - docker pull $MY_IMAGE || true
    # Build and push Docker images to the Gitlab registry
    - docker-compose -f docker-compose.ci.build.yml build
    - docker push $MY_IMAGE
  only:
    - master

test:
  stage: test
  script:
    # Pull the image
    - docker pull $MY_IMAGE
    # Start the containers and run the tests before deployment
    - docker-compose -f docker-compose.ci.test.yml up -d
    # TODO: The following always succeeds instantly with "-T" flag,
    # but won't run at all if I exclude the "-T" flag...
    - docker-compose -f docker-compose.ci.test.yml exec -T web_service pytest --junitxml=report.xml
    - docker-compose -f docker-compose.ci.test.yml down
  artifacts:
    when: always
    paths:
      - report.xml
    reports:
      junit: report.xml
  only:
    - master

deploy:
  stage: deploy
  script:
    - bash deploy.sh
  only:
    - master

标签: dockerdocker-composepytestgitlab-cigitlab-ci-runner

解决方案


我在这里找到了解决方案。这是一个怪癖docker-compose exec。相反,我找到了容器 ID$(docker-compose -f docker-compose.ci.test.yml ps -q web_service)并使用docker exec --tty <container_id> pytest ...

在这个test阶段,我做了以下替换:

test:
  stage: test
  script:
    - # docker-compose -f docker-compose.ci.test.yml exec -T myijack pytest /app/tests/ --junitxml=report.xml
    - docker exec --tty $(docker-compose -f docker-compose.ci.test.yml ps -q web_service) pytest /app/tests --junitxml=report.xml

推荐阅读