在Docker容器中将py.test作为服务运行

12

我正在设置一个基于Docker的Selenium网格。我可以通过附加到一个pytest容器[如下所示]来发送我的Python测试[使用pytest运行]。但是,我设置了另一个LAMP容器来控制pytest。所以,我想让pytest容器独立运行,处于空闲状态,并等待来自LAMP容器的命令。

我有这个Dockerfile:

# Starting from base image
FROM ubuntu

#-----------------------------------------------------
# Set the Github personal token
ENV GH_TOKEN blablabla

# Install Python & pip
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y python python-pip python-dev && pip install --upgrade pip

# Install nano for #debugging
RUN apt-get install -y nano

# Install xvfb
RUN apt-get install -y xvfb

# Install GIT
RUN apt-get update -y && apt-get install git -y

# [in the / folder] 
RUN git clone https://$GH_TOKEN:x-oauth-basic@github.com/user/project.git /project

# Install dependencies via pip
WORKDIR /project
RUN pip install -r dependencies.txt
#-----------------------------------------------------

#
CMD ["/bin/bash"]

我手动启动pytest容器[用于开发],使用以下命令:

docker run -dit -v /project --name pytest repo/user:py

问题是我已经完成了开发工作,我想要从docker-compose启动pytest容器,并将其连接到其他容器[使用link和volume]。但我无法使它保持运行。

我使用了以下代码:

pytest:
  image: repo/user:py
  volumes:
    - "/project"
  command: "/bin/bash tail -f /dev/null"

但是并没有生效。

因此,在Dockerfile内部,我应该使用特定的CMD还是ENTRYPOINT?

我应该使用docker-compose文件中的某些command吗?


你的 docker run 后面有个 -dit,这很奇怪,它应该只有 d 或 it 中的一个,而不是两个都有。另外,你的 Dockerfile 应该有一个 CMD 或 ENTRYPOINT。 - user2915097
我首先使用-dit启动它,这样我就可以获得自由控制台,然后我使用compose启动了另一个容器,该容器依赖于第一个容器已经启动。我知道它应该是这样的,但是如何保持其运行的命令是什么? - Kostas Demiris
1
@user2915097 的意思是,你不需要 it,只需要 -d 将容器作为守护进程(后台)运行。-it 用于交互式地运行容器并分配一个 tty - Auzias
我明白。我可以使用“-d”在后台运行,并且仍然可以使用主机控制台并随后连接到容器。 - Kostas Demiris
4个回答

8

我最近在一个项目中启用了它。我使用多阶段构建。目前,我将测试放在与源代码相同的文件夹中test_*.py。从我的经验来看,这样做感觉不自然,我更喜欢测试在其自己的文件夹中,默认情况下应该被排除。

FROM python:3.7.6 AS build
WORKDIR /app
COPY requirements.txt .
RUN pip3 install --compile -r requirements.txt && rm -rf /root/.cache
COPY src /app
# TODO precompile

# Build stage test - run tests
FROM build AS test
RUN pip3 install pytest pytest-cov && rm -rf /root/.cache
RUN pytest --doctest-modules \
  --junitxml=xunit-reports/xunit-result-all.xml \
  --cov \
  --cov-report=xml:coverage-reports/coverage.xml \
  --cov-report=html:coverage-reports/

# Build stage 3 - Complete the build setting the executable
FROM build AS final
CMD [ "python", "./service.py" ]

为了从覆盖率测试中排除测试文件,必须存在.coveragerc
[run]
omit = test_*
test 目标运行所需的测试,并生成覆盖率和执行报告。这些内容不适用于Azure DevOps 和 SonarQube。为了使其适用,需要进行以下操作:
sed -i~ 's#/app#$(Build.SourcesDirectory)/app#' $(Pipeline.Workspace)/b/coverage-reports/coverage.xml

运行测试

#!/usr/bin/env bash
set -e
DOCKER_BUILDKIT=1 docker build . --target test --progress plain

非常出色的解决方案,只是希望 docker build 可以将 pytest 的颜色编码转发到控制台。你能否也将其与 Github actions 集成?我计划编写完整的流水线并自动化它,但我对这个主题还比较陌生。 - Alvin
1
我的一位面试候选人在他们的工作申请中做了类似的事情。虽然不是Python,但仍然是一个多阶段的Docker构建,所以我知道这是可能的。 - Archimedes Trajano

5
我不确定你的测试是如何执行的,但我认为我的用例类似。您可以在我的Envoy项目的cmd.sh和一个样本测试中查看我如何做到这一点。
以下是我的测试运行方式。我也使用pytest,但这并不重要: 1.使用docker-compose启动堆栈,但不包括测试。 2.等待堆栈准备好请求。对我来说,这意味着轮询200响应。 3.单独运行测试容器,但确保它使用与compose堆栈相同的网络。
这可以通过多种方式完成。您可以将所有内容放入Bash脚本中,并从主机控制所有内容。
在我的情况下,我全部在Python容器中完成。这有点难以理解,但想法是有一个Python测试容器,主机启动它。然后容器本身使用compose在主机上恢复堆栈(dockerception)。然后在测试容器中运行pytest测试。完成时,它会组合关闭堆栈并推送返回代码。

0

首先,您必须使用“docker images”获取图像列表。 然后查看列表,确保您的镜像存在。 因此,请使用“docker run”运行您的Docker镜像。

不要忘记这个注意事项:您必须在DockerFile中CMD以使用容器运行pytest。


-1

我的Dockerfile

FROM python:3.6-slim

COPY . /python-test-calculator

WORKDIR /python-test-calculator

RUN pip freeze > requirements.txt

RUN pip install --no-cache-dir -r requirements.txt

RUN mkdir reports

CMD cd reports 

CMD [python", "-m", "pytest", "--junitxml=reports/result.xml"]

CMD tail -f /dev/null

needs code sections - Moein Moeinnia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接