docker - Pytest 不能在带有 Docker-Compose 的 Gitlab CI Docker 执行器中使用“docker-compose exec -T web_service pytest”运行
问题描述
我尝试使用 Gitlab CI 的主要原因是在部署之前自动化单元测试。我想要
- 构建我的 Docker 映像并将它们推送到我的映像存储库,然后
- 确保我所有的 pytest 单元测试都通过,最后
- 部署到我的生产服务器。
-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
解决方案
我在这里找到了解决方案。这是一个怪癖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
推荐阅读
- sql-server - 在 datagridview 上加载数据的更快方法?
- mysql - 具有来自不同表的字段的人员列表
- eslint - 在 webpack 的单独进程中运行 eslint
- javascript - 如何在钩子中传递对象参数?
- python - 服务器列表期间的openstackclient python错误
- macos - 基于操作系统的隐藏按钮
- codeigniter - 使用路径 Codeigniter 上传图片
- html - 如何在插入英雄图像顶部的图像下插入标题
- javascript - 如何永久更改 js 数组对象
- asp.net-core - 如何设置 Swashbuckle/swagger-ui 以在多部分/表单数据请求中将字符串数组呈现为逗号分隔并正确引用?