Pytest-常用装饰器

>fixture

fixture实现前置操作

[申明]

  1. 不带参数 @pytest.fixture
  2. 带参数 @pytest.fixture(scope="function", params=None, autouse=False, ids=None, name=None)
@pytest.fixture()
def login():
    print('登录')
@pytest.fixture(autouse=True)
def get_info():
    print('获取信息')

[调用方式]

  1. 做为参数传入
  2. 测试用例加上装饰 @pytest.mark.usefixtures(fixture_name)
@pytest.mark.usefixtures('get_info')
def test_demo3():
    print('get info')

def test_demo1(self,login):
    print('get user name ')

[参数说明]

scope:

  1. function(默认)--每个函数前运行
  2. class--class 前运行一次
  3. module--整个.py文件运行一次
  4. package--整个package下运行一次
  5. session--整个会话过程运行一次
@pytest.fixture(scope='module')
def login():
    print('登录')
def test_demo3(login):
    print('get info')
class Test_Demo():
    def test_demo3(self, login):
        print('get user sex ')

def test_demo1(self, login):
    print('get user name ')

autouse:默认:False,需要用例手动调用该fixture;如果是True,所有作用域内的测试用例无需显示调用都会自动调用该fixture

@pytest.fixture(autouse=True)
def login():
    print('登录')
def test_demo3():
    print('get info')
class Test_Demo():
    def test_demo3(self):
        print('get user sex ')
    def test_demo1(self):
        print('get user name ')

name:默认:装饰器的名称,同一模块的fixture相互调用建议写个不同的name

多fixture:

#使用装饰器调用时,底部先执行
@pytest.mark.usefixtures('login')
@pytest.mark.usefixtures('get_info')
def test_demo3():
    print('get info')
#使用参数调用时,前面的先执行
class Test_Demo():
    def test_demo4(self,login,get_info):
        print('get user sex ')

fixture 带参

1.调用时只可用参数调用

2.申明时参数带request,获取参数为request.param

3.传参装饰器需带参indirect=True,标识参数当函数执行。否则申明的fixture不会执行

单参

sex = ['g', 'b']

@pytest.fixture()
def login(request):
    name = request.param
    print('login para is {}'.format(name))
@pytest.mark.parametrize('login',sex,indirect=True)
def test_demo3(login):
    print('get info')

多参--数据为字典格式

para2 = [
    {'name':name[1],'tel':tel[1]},
    {'name':name[2],'tel':tel[2]}
]

@pytest.fixture()
def login(request):
    name = request.param
    print('login name is {} ans tel is {}'.format(name['name'],name['tel']))
@pytest.mark.parametrize('login',para2,indirect=True)
def test_demo3(login):
    print('get info')

多个fixture,一个传参装饰器:数据按传参顺序分发到各个fixture中

para2 = [
    [name[1],tel[1]],
    [name[2],tel[2]]
]

@pytest.fixture()
def name(request):
    name = request.param
    print('login name is {} '.format(name))
@pytest.fixture()
def sex(request):
    sex = request.param
    print('login sex is {} '.format(sex))
@pytest.mark.parametrize('name,sex',para2,indirect=True)
def test_demo3(name,sex):
    print('get info')

多个fixture,多个装饰器--执行用例为笛卡尔积

[备注]数据名与函数名不要一致,容易报错

sex_data = ['g', 'b']
name_data = ['april', 'kka']

@pytest.fixture()
def name(request):
    name = request.param
    print('login name is {} '.format(name))

@pytest.fixture()
def sex(request):
    sex = request.param
    print('login sex is {} '.format(sex))

@pytest.mark.parametrize('name', name_data, indirect=True)
@pytest.mark.parametrize('sex', sex_data, indirect=True)
def test_demo5(name, sex):
    print('get info')

fixture 可返回数据

@pytest.fixture()
def name(request):
    name = request.param
    return name

@pytest.mark.parametrize('name', name_data, indirect=True)
def test_demo5(name):
    print('get name is {}'.format(name))

fixture实现后置操作

  1. yield关键字

    1.1 fixture申明的函数,添加yield关键字,yield之前得部分为前置,之后的部分为后置

    1.2 若yield之前得部分抛异常,则后置也不执行

    1.3 若用例抛异常,后置照常执行

    1.4 yield 可返回前置操作返回的数据

@pytest.fixture()
def demo_fixture():
    print("\n这个fixture在每个case前执行一次")
    yield
    print("\n在每个case完成后执行的teardown")

def test_01(demo_fixture):
    print("\n===执行了case: test_01===")
  1. addfinalizer

    1.注册作为终结器使用的函数

    2.request.addfinalizer(function_finalizer)

@pytest.fixture(scope="module")
def test_addfinalizer(request):
  # 前置操作setup
  print("==再次打开浏览器==")
  test = "test_addfinalizer"
  def fin():
      # 后置操作teardown
      print("==再次关闭浏览器==")
  request.addfinalizer(fin)
  return test

def test_anthor(test_addfinalizer):
  print("==最新用例==", test_addfinalizer)
  1. addfinalizer可以注册多个终结函数。即可执行多个不同后置操作。执行顺序,与注册的顺序相反

  2. 当setUp的代码执行错误,addfinalizer依旧会执行

fixture调用范围

同变量的使用,定义在类中的fixture,只有类中test可调用;定义在module中的fixture,module中test皆可调用.

fixture调用fxiture,则无范围限制。皆可调用.

@pytest.fixture
def order():
    return []

@pytest.fixture
def outer(order, inner):
    order.append("outer")

class TestOne:
    @pytest.fixture
    def inner(self, order):
        order.append("one")

    def test_order(self, order, outer):
        assert order == ["one", "outer"]

conftest.py

全局fixture,无需引用,直接调用

Factories as fixtures

fixture传数据

@pytest.fixture
def make_customer_record():
    def _make_customer_record(name):
        return {"name": name, "orders": []}

    return _make_customer_record

def test_customer_records(make_customer_record):
    customer_1 = make_customer_record("Lisa")
    customer_2 = make_customer_record("Mike")
    customer_3 = make_customer_record("Meredith")
    customer = [customer_1,customer_2,customer_3]
    print('data is {}'.format(customer))

>Mark

1.注册

​ 1.1 在pytest.ini文件中注册

[pytest]
markers =
    slow: marks tests as slow (deselect with '-m "not slow"')
    serial

1.2 在pyproject.toml文件中注册

[tool.pytest.ini_options]
markers = [
    "slow: marks tests as slow (deselect with '-m \"not slow\"')",
    "serial",
]

1.3 hook函数中注册

def pytest_configure(config):
    config.addinivalue_line(
        "markers", "env(name): mark test to run only on named environment"
    )

2.使用

2.1使用前标记 @pytest.mark.name_of_the_mark

2.2 命令行 -m name_of_the_mark

2.3 使用非系统默认未注册的mark会报错

讨论数量: 0

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!