pytest中Hook 方法注册命令行参数06
场景
1.一般公司测试环境都有多套,测试的时候我们需要在不同的环境下进行
2.在自动化执行时,在不同的环境下我们要指定不同的系统配置,每次修改框架代码配置这个很不自动化
3.pytest_addoption注册参数 这个就很好的解决了这个问题,它能在执行命令的时候传递参数
(此外,还可使用插件pytest-base-url进行命令行传参切换环境,本次不展开讨论)
1、Hook方法注解:
- pytest_addoption:可以让用户注册一个自定义的命令行参数,方便用户将数据传递给 pytest
- 这个 Hook 方法一般和内置 fixture pytestconfig 配合使用
- pytest_addoption 注册命令行参数,pytestconfig 通过配置对象读取参数的值
- 参考文档:https://docs.pytest.org/en/latest/writing_plugins.html#using-hooks-in-pytest-addoption
2、代码讲解
pytest_addoption注册、pytestconfig获取命令行参数
import pytest
# 注册自定义参数 cmdopt 到配置对象
def pytest_addoption(parser):
parser.addoption("--cmdopt", action="store",
default="这个是默认值...",
help="将命令行参数 ’--cmdopt' 添加到 pytest 配置中")
# 从配置对象中读取自定义参数的值
@pytest.fixture(scope="session")
def cmdopt(request):
return request.config.getoption("--cmdopt")
# 将自定义参数的值打印出来
@pytest.fixture(autouse=True)
def fix_1(cmdopt):
print('\n --cmdopt的值:', cmdopt)
if __name__ == '__main__':
# 使用参数
pytest.main(['-s', '--cmdopt=98k'])
实际结果:

查询原因:没有安装相关包的原因引起的,具体什么包不清楚,按理说已经定义了相关函数
正常结果:控制台打印参数值
============== test session starts =============
test_Z.py::TestDemoA::test_A_001
--cmdopt的值: 98k
PASS
============ 1 passed in 0.02s ================
3、parser.addoption() 参数说明:
1、name:自定义命令行参数的名字,可以是:"foo", "-foo" 或 "--foo";
2、action:在命令行中遇到此参数时要采取的基本操作类型;
3、nargs:应该使用的命令行参数的数量;
4、const:某些操作和nargs选择所需的常量值;
5、default:如果参数不在命令行中,则生成的默认值。
6、type:命令行参数应该转换为的类型;
7、choices:参数允许值的容器;
8、required:命令行选项是否可以省略(仅可选);
9、help:对参数作用的简要说明;
10、metavar:用法消息中参数的名称;
11、dest:要添加到 parse_args() 返回的对象中的属性的名称;
常用的参数详解:
- name:这个不用多说,自定义的参数的名字;
def pytest_addoption(parser):
parser.addoption("--cmdopt", action="append",
default=[100],
choices=['python','java','c++'],
type=int,
help="将命令行参数 ’--cmdopt' 添加到 pytest 配置中")
if __name__ == '__main__':
# 使用参数
pytest.main(['-s', '--cmdopt'])
2、action="store":默认,只存储参数的值,可以存储任何类型的值,此时 default 也可以是任何类型的值,而且命令行参数多次使用也只能生效一个,最后一个值覆盖之前的值;
3、action="append":存储一个列表,用 append 模式 将可以同时多次使用自定义参数,并且 default 默认值必须是一个列表,pytest 会把 default 默认参数的值和多个自定义参数的值放在一个列表中:
pytest.main(['-s', '--cmdopt=98k','--cmdopt=毛枪'])
--cmdopt的值: ['这是默认参数', '98k', '毛枪']
4、 type:type 的类型可以是 python 的基础类型,比如:int,str,float,list 等类型,如果不指定类型的话,pytest会把接受到的参数值都默认为 str 类型,所以我们有时需要指定参数的类型:
注意:在使用 type 指定类型时,也需要把 default 的类型修改为同样的类型!
5、choices:choices 可以指定几个值,自定义参数必须在这几个值中选择一个,否则会报错:
5、实际场景应用:
1.一般编写到conftest.py文件中
2.定义pytest_addoption方法注册pytest命令行参数,函数名和参数保持一致
def pytest_addoption(parser):
"""注册自定义参数 env 到配置对象"""
parser.addoption("--env", action="store",
default="https://www.cnblogs.com/",
help="将命令行参数 ’--env' 添加到 pytest 配置中")
3.使用request.config.getoption("--命令行")获取命令行参数的值
@pytest.fixture(scope="session")
def get_env(request):
"""从配置对象中读取自定义参数的值"""
return request.config.getoption("--env")
4.fixture继承,进行环境切换
@pytest.fixture(autouse=True)
def set_env(get_env):
"""将自定义参数的值写入全局配置文件"""
with open(ENV_TXT_FILE, 'w', encoding='utf-8') as f:
f.write(get_env)
5.通过pytest命令行传参一键化实现环境切换和测试用例执行
pytest --env=https://www.cnblogs.com/
PS:Hook不局限于环境切换,任何想通过pytest命令行传入自定义的参数都可以实现