直接用 pytest 的 --env 参数 + conftest.py 加载逻辑即可实现环境分离:先在 conftest.py 中通过 pytest_addoption 注册 --env 参数并设默认值,再用 pytest_configure 提前读取对应 config/{env}.json 并挂载到 config._config,最后通过 fixture 或 request.node.config._config 统一获取;该方案显式可审计、支持多环境并发运行、避免 OS 环境变量污染与 CI 隐患。

直接用 pytest 的 --env 参数 + 自定义 conftest.py 加载逻辑,就能干净分离 dev/staging/prod 配置,不用改代码、不硬编码、不依赖环境变量。
怎么让 pytest 启动时读取指定环境的配置文件
pytest 本身不内置环境切换机制,得靠命令行参数驱动配置加载。核心是两步:注册自定义参数,再在 conftest.py 里解析它并注入配置对象。
- 在项目根目录下新建
conftest.py,用pytest_addoption注册--env参数:def pytest_addoption(parser): parser.addoption( "--env", action="store", default="dev", help="Environment to run tests against: dev/staging/prod" ) - 用
pytest_configure提前加载配置,避免测试中重复读取:import json import os def pytest_configure(config): env = config.getoption("--env") config_file = f"config/{env}.json" if not os.path.exists(config_file): raise RuntimeError(f"Config file {config_file} not found") with open(config_file) as f: config._config = json.load(f) - 这样所有测试函数都能通过
request.node.config._config或 fixture 获取配置,比如写个configfixture:@pytest.fixture def config(request): return request.node.config._config
为什么不能只靠 OS 环境变量切换配置
单纯用 os.environ.get("ENV") 在 CI/CD 中容易污染、难追溯,且无法支持单次运行多环境(比如同时跑 dev 和 staging 的 smoke 测试)。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
-
--env=staging是显式、可审计、可复现的;ENV=staging pytest依赖 shell 环境,CI 脚本里容易漏设或覆盖 - 多个测试套想用不同配置?加
--env=dev和--env=prod分两次跑就行,环境变量做不到这点 - pytest 参数会自动出现在
pytest --help里,团队新人一眼就知道怎么切环境
配置文件路径和结构怎么组织才不容易出错
推荐按 config/dev.json、config/staging.json、config/prod.json 组织,顶层字段保持一致,避免测试里写 cfg.get("db_url") or cfg.get("database_url") 这种容错逻辑。
立即学习“Python免费学习笔记(深入)”;
- 所有配置文件必须有相同 key 结构,比如都含
"api_base"、"timeout"、"auth_token",缺失字段在pytest_configure阶段就报错,而不是某个 test case 失败才暴露 - 敏感字段(如
auth_token)在 prod 配置里留空或设为null,CI 中通过 secret 注入,本地 dev 用明文,避免把 prod token 提交进 git - 不要用
.py文件当配置——执行风险高,且 pytest 会把它当测试模块扫描,可能意外触发 import side effect
最常被忽略的是配置校验:很多人只做文件存在性检查,但没验证 JSON 格式是否合法、必需字段是否缺失。加一行 jsonschema.validate(cfg, schema) 能省掉后续一半 debug 时间。

















