setup和teardown
分为:模块级,类级,方法级,函数级
setup_module()/teardown_module()
setup_function()/teardown_function()
setup_class()/teardown_class()
setup_method()/teardown_method()
fixture装饰器
pytest.fixture(scope="function", params=None, autouse=False, ids=None, name=None)
参数说明:
scope
:表示被@pytest.fixture()
装饰器所标识方法的作用域。作用域有四个级别,函数function(默认)
,类class
,模块module
,包package/session
。params
:一个可选的参数列表,用于做Fixture的参数化。可将数据提供给其他的Fixture,或者所有测试使用它 。autouse
:autouse=Ture
则开启自动使用Fixture功能,也是调用Fixture函数一种方法。Fixture装饰器会自动执行作用域范围内的所有用例的前后置。autouse
默认值为Flase。ids
:一个字符串id的列表,即当使用params参数化时,给每一个值设置一个变量名。如果没有提供ID,params将自动生成ID 。name
:表示给被@pytest.fixture()
装饰器修饰的方法取一个别名,调用时可以使用别名调用。默认为装饰器所装饰的函数名称。
fixture实现setup和teardown
使用yield
- 直接使用
@pytest.fixture()
标记的函数,实现setup。 - 在
@pytest.fixture()
标记的函数中使用yield
实现teardown,在yield后面加参数可以进行参数传递 @pytest.fixture(params=xxx)
标记的函数传入参数request
(固定写法),使用request.param
获取参数
- params参数支持的格式
- 列表
[ ]
, - 元组
( )
, - 元素列表
[(),(),()]
, - 字典列表
[{},{},{}]
,提示:只能取{}
整体。 - 字典元祖
({},{},{})
,提示:只能取{}
整体。
# setup
@pytest.fixture()
def before():
print('before---------')
def test_f1(before):
assert 1==1
# setup 和 teardown
@pytest.fixture()
def before_after():
print('before---------')
yield
print('after----------')
def test_f2(before_after):
assert 2==2
# 传递参数 1
@pytest.fixture()
def deliver_param():
print('before---------')
str='aabb'
yield str
print('after----------')
def test_f3(deliver_param):
assert deliver_param=='aabb'
# 传递参数 2
@pytest.fixture(params={'s1':1,'s2':2})
def deliver_param2(request):
return request.params
def test_f4(deliver_param2):
for x in deliver_param2:print(x)
使用addfinalizer
(TODO)
@pytest.fixture()
标记的函数需要传入参数request
,固定写法- 使用
request.addfinalizer(teardown)
添加teardown,后面可以return一个返回值
@pytest.mark.usefixtures()
usefixtures
与传fixture
区别:
如果Fixture有返回值,则不能用@pytest.mark.usefixtures("fixturename")
装饰器修饰用例。
如果Fixture没有返回值,用@pytest.mark.usefixtures("fixturename")
装饰器和@pytest.fixture()
装饰器作用一样。
conftest.py
conftest.py
文件,可以在这个文件里面编写Fixture函数,这个Fixture函数的作用,Pytest框架会自动去找conftest.py
文件里面的东西。
conftest.py
文件是单独存放的一个Fixture配置文件,名称是不能更改。可以在不同的.py
文件中使用同一个Fixture函数。conftest.py
需要和运行的用例放到同一目录中,并且有__init__.py
文件,那么conftest.py
作用于整个目录。如果希望Fixture共享给所有测试,则可以把conftest.py
文件放在测试框架的根目录下。conftest.py
文件中的内容,不需要做任何的imprt
导入的操作就能够读取到,因为Pytest用例会自动查找。
pytest参数化
pytest有三种传参方式,主要用到前两种
@pytest.mark.parametrize()
装饰器方式进行参数化。(常用)pytest.fixture()
方式进行参数化,fixture
装饰的函数可以作为参数传入其他函数。conftest.py
文件中存放参数化函数,可作用于模块内的所有测试用例。
@pytest.mark.parametrize()
@pytest.mark.parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)
argnames
:参数名,使用逗号分隔的字符串,或列表或元祖,表示一个或多个参数名。(常用参数)argvalues
:参数值,类型可以是列表,元祖,字典列表,字典元祖,有多个值用例就会执行多少次。(常用参数)indirect
:当indirect=True
时,若传入的argnames
(参数)是Fixture函数名,此时Fixture函数名将是一个可执行的函数,Fixture装饰器返回的数据作为argnames
的参数,最终结果会存入request.param
中。当indirect=False
时,Fixture函数只作为一个参数名,给测试收集阶段调用。ids
:字符串列表,可以理解成给前面的argvalues
参数起别名,别名个数和数据的值相同。scope
:如果指定,则表示参数的使用范围。
names=['tom','jerry','jack']
@pytest.mark.parametrize("data1",names)
def test_func1(data1):
print('name={0}'.format(data1))
info=[('tom',18),('jerry',17)]
@pytest.mark.parametrize('name,age',info)
def test_func2(name,age):
print('name={0},age={1}'.format(name,age))
s1=[{'name':'tom','age':18}]
@pytest.mark.parametrize('data2',s1)
def test_func3(data2):
print('name={0},age={1}'.format(data2['name'],data2['age']))
自定义命令行参数 pytestconfig
使用 pytestconfig
,可以很方便的读取命令行参数和配置文件。
下面示例演示命令行参数解析:首先在 conftest.py
中使用函数 pytest_addoption, 结合
@pytest.fixture 使用:
# conftest.py
def pytest_addoption(parser):
parser.addoption('--host', action='store',
help='host of db')
parser.addoption('--port', action='store', default='8888',
help='port of db')
@pytest.fixture
def cmd_param(pytestconfig):
host=pytestconfig.getoption('host')
port=pytestconfig.getoption('port')
yield host,port
然后就可以在测试函数中通过 @pytest.fixture 获取命令行参数:
# test_config.py
def test_01(cmd_param):
host,port=cmd_param
print('host={},port={}'.format(host,port))