pytest进阶(二)

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,或者所有测试使用它 。

  • autouseautouse=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']))

 

原文地址:https://www.cnblogs.com/yjh1995/p/14753241.html