如何在Docker中自动化运行Python API测试脚本?
问题背景
我创建了一个Flask应用,可在localhost/api提供JSON数据,同时使用Nginx和Gunicorn搭建服务器,整个应用已用Docker容器化。
Dockerfile
FROM python:3.10 ENV CONTAINER_HOME=/var/www ADD . $CONTAINER_HOME WORKDIR $CONTAINER_HOME RUN pwd RUN pip3 install -r $CONTAINER_HOME/requirements.txt # RUN python3 $CONTAINER_HOME/src/tests/tests.py ???? Should I add this line?
docker-compose.yml
version: '3.8' services: nginx: image: nginx:1.25 container_name: nginx volumes: - ./nginx-config/nginx.conf:/etc/nginx/conf.d/default.conf ports: - 80:80 networks: - my-network depends_on: - flask flask: build: context: ./ dockerfile: Dockerfile container_name: flask command: gunicorn --bind 0.0.0.0:8000 "src.api.app:app" volumes: - ./:/var/www networks: my-network: aliases: - project networks: my-network:
需求与问题
我已编写好Python测试脚本tests.py,在本地环境可正常运行,现希望在Docker容器中自动化执行API测试,而非在主机终端手动操作。
问题:
- 如何在Docker容器中自动化完成API测试?
- 需在容器启动且JSON数据可用后,再运行
tests.py对localhost/api的JSON数据进行测试。
请问该如何解决?是在Dockerfile、docker-compose.yml中配置,还是需创建单独目录和Dockerfile来运行测试脚本?
解决方案
方案一:添加独立测试服务(推荐)
在docker-compose.yml中新增专门的测试服务,既不干扰主应用运行,又能保证测试在API就绪后执行。
- 修改
docker-compose.yml,新增tests服务:
version: '3.8' services: nginx: # 原nginx配置保留 image: nginx:1.25 container_name: nginx volumes: - ./nginx-config/nginx.conf:/etc/nginx/conf.d/default.conf ports: - 80:80 networks: - my-network depends_on: - flask flask: # 原flask配置保留 build: context: ./ dockerfile: Dockerfile container_name: flask command: gunicorn --bind 0.0.0.0:8000 "src.api.app:app" volumes: - ./:/var/www networks: my-network: aliases: - project tests: build: context: ./ dockerfile: Dockerfile container_name: tests command: > sh -c " until curl -s http://nginx/api; do echo 'Waiting for API to be ready...' sleep 2 done python3 src/tests/tests.py " volumes: - ./:/var/www networks: - my-network depends_on: - nginx - flask
- 核心说明:
- 测试服务复用原Dockerfile,无需额外构建环境
- 通过
until curl循环检查API状态,避免容器启动但服务未就绪就执行测试 - 测试脚本中不能用
localhost/api,要改用Docker网络内的服务地址http://nginx/api(服务名直接作为域名使用)
方案二:在Flask容器启动后执行测试(仅适合一次性测试)
如果不想新增服务,可修改Flask的启动命令,先启动服务再执行测试,但会导致主服务在测试完成后才持续运行,仅适合单次测试场景:
flask: # 其他配置保留 command: > sh -c " gunicorn --bind 0.0.0.0:8000 'src.api.app:app' & PID=$! until curl -s http://project:8000/api; do echo 'Waiting for Flask app to be ready...' sleep 2 done python3 src/tests/tests.py wait $PID "
方案三:构建阶段执行测试(排除)
你之前考虑的在Dockerfile中添加RUN python3 ...的方式,仅适用于不需要依赖运行中服务的单元测试,构建阶段没有启动的Flask服务,无法测试localhost/api,直接排除。
关键注意事项
- 测试脚本中的API地址必须使用Docker网络内的服务名,不能用
localhost depends_on仅保证容器启动,不保证服务内部就绪,必须添加就绪检查逻辑- 优先选择独立测试服务,主应用与测试分离,测试完成后容器自动退出,不影响主服务运行
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

