必须在conftest.py中定义pytest_addoption钩子函数注册参数,通过request.config.getoption()在测试函数内读取,default值必设且ini文件中的addopts仅对已声明参数生效。

如何在conftest.py中注册pytest自定义命令行参数
pytest不支持直接在测试函数里读取命令行参数,必须通过conftest.py中的pytest_addoption钩子注册。这个函数只在pytest初始化阶段执行一次,错过就无法注入参数。
常见错误是把参数注册写在test_*.py文件里,或误用parser.add_argument()(这是argparse的写法,pytest用parser.addoption())。
- 必须放在项目根目录或测试目录下的
conftest.py中,且文件名不能拼错 - 注册时要指定
action类型:布尔值用'store_true',字符串用'store',避免默认'store_const'导致值为空 - 推荐加
default值,否则未传参时request.config.getoption(...)会抛ValueError
def pytest_addoption(parser):
parser.addoption(
"--env",
action="store",
default="staging",
help="运行环境:dev/staging/prod"
)
parser.addoption(
"--skip-slow",
action="store_true",
default=False,
help="跳过标记为slow的测试"
)
如何在测试函数中安全获取和使用自定义参数
不能直接调用sys.argv或手动解析,必须通过pytest内置的request fixture访问。fixture名固定为request,且必须作为函数参数显式声明。
容易踩的坑是试图在setup_method或@pytest.mark.parametrize中提前读取——此时request.config可能尚未就绪,应统一在测试函数体内获取。
- 用
request.config.getoption("--env")读取,注意参数名带双横线前缀 - 布尔型参数返回
True/False,字符串型返回str,无需额外转换 - 若参数用于条件跳过,建议配合
pytest.skip()而非if/else包裹逻辑,否则未跳过的测试仍会执行setup
def test_api_endpoint(request):
env = request.config.getoption("--env")
if env == "prod":
pytest.skip("生产环境不执行此测试")
# 后续逻辑...
如何让自定义参数影响pytest的测试选择逻辑
单纯读取参数只能做运行时判断,若想实现“动态筛选测试集”,需结合pytest_collection_modifyitems钩子。这个钩子在收集完所有测试项后、执行前触发,可修改items列表。
华为云 Python SDK 查询工具。自动发现已安装 SDK 的服务包、Client类、API 方法、入参详情、类信息(__init__ 参数、属性、类型、描述),支持关键字搜索,快速定位目标 API 使用方法。
典型场景是根据--env自动跳过某些标记的测试,或按参数值过滤test_*.py文件。但要注意:修改items是原地操作,不能直接return新列表。
- 必须用
items[:] = [...]或items.clear()+items.extend(...)来替换内容 - 跳过逻辑建议用
item.add_marker(pytest.mark.skip(reason=...)),比直接移除更利于报告统计 - 避免在钩子里调用
request.config.getoption()以外的fixture,此时其他fixture尚未初始化
def pytest_collection_modifyitems(config, items):
env = config.getoption("--env")
if env == "dev":
skip_dev = pytest.mark.skip(reason="开发环境跳过集成测试")
for item in items:
if "integration" in item.keywords:
item.add_marker(skip_dev)
为什么pytest.ini里不能配置自定义参数的默认值
pytest.ini只能设置pytest内置参数(如addopts、testpaths),对pytest_addoption注册的参数无效。试图在ini里写env = staging不会被识别,也不会报错,只是静默忽略。
真正生效的默认值只来自pytest_addoption里的default参数。如果需要多环境配置,应靠CI脚本传参或用环境变量兜底,而不是依赖配置文件。
- CI中建议统一用
pytest --env=$ENV_NAME,避免不同环境读错配置 - 本地调试时可用
pytest --env=dev -v快速切换,比改代码更安全 - 参数名不要用下划线(如
--test_env),部分shell环境会截断,坚持用短横线分隔
参数注册和消费的时机差得很细,钩子函数名拼错、conftest位置不对、default缺失——这三个点占了80%的失败案例。跑之前先pytest --help确认参数是否出现在输出里,比debug更快。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










