必须显式创建虚拟环境,否则 pytest 很可能因依赖混杂而静默失败;gitlab runner 的 python:3.9-slim 镜像不预装项目依赖且不隔离环境,直接 pip install 会污染系统 site-packages,引发 importerror、版本错乱、覆盖率归零及缓存失效等问题。

必须显式创建虚拟环境,否则 pytest 很可能因依赖混杂而静默失败。
为什么不能跳过 venv 直接用系统 Python
GitLab Runner 的 python:3.9-slim 镜像虽带 Python,但不预装项目依赖,也不隔离环境。直接 pip install -r requirements.txt 会写入系统 site-packages,导致:
-
ImportError或AttributeError:比如本地开发用pytest==7.4.3,CI 中却加载了镜像自带的pytest==6.2.5 - 测试通过但覆盖率归零:
pytest-cov无法正确追踪源码路径,因--cov=src在非虚拟环境中找不到对应模块安装路径 - 缓存失效:不同 job 共享同一 site-packages,Python minor 版本升级(如 3.9 → 3.10)后 wheel 缓存直接报
ImportError: bad magic number
实操建议:before_script 中固定执行:
python -m venv venv && source venv/bin/activate
后续所有 pip install 和 pytest 命令都基于此环境运行。
pytest 参数必须显式指定路径与报告格式
CI 中 pytest 默认不递归扫描 tests/ 下所有文件,尤其当测试模块缺失 __init__.py、或使用 check_*.py 这类非标准命名时,会出现 No tests were found。
调用 Cutout.Pro 视觉处理 API 进行背景移除、人像抠图和照片增强,支持文件上传与图片 URL 输入。
- 永远不要只写
pytest—— 必须指定目录:pytest tests/ - 覆盖率要对准源码位置:
--cov=src(若源码在src/)或--cov=app(若源码在app/) - CI 日志需可解析:用
--cov-report=xml生成cov.xml,GitLab 才能自动提取数值;避免只用--cov-report=term - 调试时加
-v和--tb=long:前者列出实际加载的测试项,后者防止关键堆栈被截断
缓存配置稍有偏差就等于没缓存
cache 是提速关键,但 GitLab 的缓存机制很“娇气”:
- 必须缓存
.cache/pip和venv/,不能只缓存venv/lib/python3.9/site-packages—— 后者随 Python 小版本变化,跨镜像会崩溃 -
key必须包含$CI_JOB_NAME和$CI_COMMIT_REF_SLUG,否则test和deployjob 会互相污染缓存 - 别用
~/.cache/pip:Runner 用户主目录不可靠,应统一用项目内相对路径.cache/pip
推荐写法:
cache:
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths:
- .cache/pip
- venv/
测试失败时第一眼该看什么
CI 流水线里 pytest 报错常被日志缓冲区截断。比如只显示:
TypeError: expected str, bytes or os.PathLike object
但没说哪行、哪个 fixture、哪个测试函数触发的。
- 根本原因:CI 默认启用
--tb=short,且不保留完整 stdout 缓冲 - 解决动作:在
script中强制加--tb=long,并确保-v开启 - 额外技巧:用
coverage run -m pytest tests/替代直接调用pytest,能绕过部分插件加载顺序问题
最易被忽略的是 venv 激活后未校验 which python 和 python -c "import sys; print(sys.executable)" —— 很多失败其实发生在激活失败却无报错的静默状态。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










