如何在Azure DevOps(服务器)管道中测试Docker化的应用程序?

12

我有一个简单的 Python 应用程序,它被 Docker 化了,其结构为:

/src
 - server.py
 - test_server.py
Dockerfile
requirements.txt

这是一个使用Linux为基础的Docker基础镜像,并使用FastAPI公开了server.py的端点。
为了完整起见,server.py看起来像这样:

from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
    number: int

app = FastAPI(title="Sum one", description="Get a number, add one to it", version="0.1.0")

@app.post("/compute")
async def compute(input: Item):
    return {'result': input.number + 1}

测试应该使用pytest进行(参考https://fastapi.tiangolo.com/tutorial/testing/),需使用test_server.py文件:

from fastapi.testclient import TestClient
from server import app
import json

client = TestClient(app)

def test_endpoint():
    """test endpoint"""
    response = client.post("/compute", json={"number": 1})
    values = json.loads(response.text)
    assert values["result"] == 2

Dockerfile看起来像这样:

FROM tiangolo/uvicorn-gunicorn:python3.7

COPY . /app

RUN pip install -r requirements.txt

WORKDIR /app/src

EXPOSE 8000

CMD ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

目前,如果我想在容器内的本地计算机上运行测试,一种方法是:

  1. 构建Docker容器
  2. 运行容器,通过 docker ps 获取其名称
  3. 运行 docker exec -it <mycontainer> bash 并执行 pytest 以查看测试通过情况。

现在,我想在推送镜像到我的Docker注册表并触发发布流程之前,在Azure DevOps (Server) 中运行测试。如果这听起来没问题,如何正确地做呢?

到目前为止,我希望在构建管线中添加“PyTest”步骤能够神奇地工作:

enter image description here

我目前正在使用Linux代理,但该步骤失败了:

enter image description here

失败并不令人惊讶,因为(我认为)容器在构建后未运行,因此pytest也无法在其中运行 :(

解决此问题的另一种方法是在Dockerfile中包含pytest命令,并在发布管线中处理测试。但我想将测试与最终推送到注册表和部署的容器分离。

是否有标准方法在Azure DevOps中在Docker容器内运行pytest并获得图形报告?


你觉得在将镜像推送到注册表之前,在Jenkins管道中运行测试怎么样?这个想法有意义吗? - bigbounty
你是如何在本地使用Docker镜像运行测试的?你能添加你的Dockerfile内容吗? - JPG
@bigbounty 我没有使用Jenkins的经验,我需要坚持使用Azure DevOps。我认为这两个工具是可以相互比较的,但不确定它们是否可以一起使用。 - Davide Fiocco
我可以再问你一件事吗?您的主要目的是在 Azure 管道中运行测试,还是通过 Docker 执行来运行测试呢? - JPG
1
@DavideFiocco 我已经添加了一个使用docker运行测试的方法。请在这里查看。 - JPG
显示剩余3条评论
3个回答

7

请按照以下方式更新您的azure-pipelines.yml文件,以在Azure Pipelines中运行测试。

方法一(使用Docker)

trigger:
- master

pool:
  vmImage: 'ubuntu-latest'
steps:
- task: Docker@2
  inputs:
    command: 'build'
    Dockerfile: '**/Dockerfile'
    arguments: '-t fast-api:$(Build.BuildId)'
- script: |
    docker run fast-api:$(Build.BuildId) python -m pytest
  displayName: 'Run PyTest'

成功的管道截图

方法二(无需 Docker)

trigger:
- master

pool:
  vmImage: 'ubuntu-latest'
strategy:
  matrix:
    Python37:
      python.version: '3.7'

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '$(python.version)'
  displayName: 'Use Python $(python.version)'

- script: |
    python -m pip install --upgrade pip
    pip install -r requirements.txt
  displayName: 'Install dependencies'

- script: |
    pip install pytest pytest-azurepipelines
    python -m pytest
  displayName: 'pytest'

顺便说一下,我有一个简单的FastAPI项目,如果你需要的话可以参考。


我可能漏掉了什么(另外,yml文件在缩进方面非常脆弱),但在第一个示例中,管道失败并显示以下错误:
  • 未指定池。
  • 意外的vmImage 'ubuntu-latest'。
- Davide Fiocco
哎呀,顺便说一句,就像大家都说的那样,“这对我有效” :D - JPG

3

使用pytest-azurepipelines测试您的Docker脚本:

- script: |
    python -m pip install --upgrade pip
    pip install pytest pytest-azurepipelines
    pip install -r requirements.txt
    pip install -e .
  displayName: 'Install dependencies'

- script: |
    python -m pytest /src/test_server.py
  displayName: 'pytest'

使用插件pytest-azurepipelines运行pytest,可以在Azure Pipelines UI中查看测试结果。 https://pypi.org/project/pytest-azurepipelines/

0

您可以使用pytest-azurepipelines直接在Docker容器内运行单元测试(需要事先在Docker镜像中安装):

    - script: |
       docker run --mount type=bind,source="$(pwd)",target=/results \
                  --entrypoint /bin/bash my_docker_image \
                  -c "cd results && pytest"
      displayName: 'tests'
      continueOnError: true

pytest 会创建一个包含测试结果的 xml 文件,并且通过 --mount 标志在 docker run 命令中使得该文件可以被 Azure DevOps pipeline 访问。然后,pytest-azurepipelines 将直接将结果发布到 Azure DevOps。


我尝试使用Docker解决方案上传覆盖率报告,但似乎出现了问题 - https://dev59.com/aHwQtIcB2Jgan1znLTQy - yardstick17

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