Python Pytest中使用的装饰器pytest.fixture

最近在pytest中使用了很多装饰器觉得很好用,现在总结一下:

pytest.fixture

 


一、通过装饰器@pytest.fixture(),定义测试固件(test fixture)。

实现setup_xxx的功能: 


import pytest
# 函数名自定义
# 此时,login函数是一个测试固件,相对于实现了setup_xxx的功能。
@pytest.fixture()
def login():
    print('登录系统')
    token = 'a1b23c'
    return token
 
# 在测试函数里, 通过形参来声明要使用的测试固件。
def test1(login):
    # 参数login的值是测试固件login函数的返回值
    print('in test1: ', login)
    print('测试1')
 
def test2(login):
    print('in test2: ', login)
    print('测试2')

实现teardown_xxx的功能


 方法一:使用yield关键字

 
import pytest
 
# 此时,login函数是一个测试固件,相当于实现了setup_xxx&teardown_xxx的功能。
@pytest.fixture()
def login():
    ############# 以下的代码相当于setup部分 ###########
    print('登录系统')
    token = 'a1b23c'
    yield token
    ############# 以下的代码相当于teardown部分 ###########
    print('退出登录')
 
# 在测试函数里, 通过形参声明要使用的测试固件
def test1(login):
    # login参数的值是测试固件函数的返回值
    print('in test1: ', login)
    print('测试1')
 
def test2(login):
    print('in test2: ', login)
    print('测试2')
 
执行结果:
登录系统
in test1:  a1b23c
测试1
.退出登录
登录系统
in test2:  a1b23c
测试2
.退出登录
 

方法二:使用request.addfinalizer()注册清理函数

import pytest
 
# login函数是一个测试固件,相当于实现了setup_xxx&teardown_xxx的功能
@pytest.fixture()
# 声明使用request测试固件
def login(request):
    print('登录系统')
    token = 'a1b23c'
    # 定义一个清理函数, 清理函数向相当于teardown_xxx
    def fin():
        print('退出登录')
    # 注册一个清理函数
    request.addfinalizer(fin)
    # 注册完清理函数后,如果在测试固件里抛出异常,只有清理函数照常执行
    # 1 / 0
    return token
 
def test1(login):
    print('in test1: ', login)
    print('测试1')
 
def test2(login):
    print('in test2: ', login)
    print('测试2')
 

可以定义和注册多个清理函数

import pytest
 
# login函数是一个测试固件,相当于实现了setup_xxx&teardown_xxx的功能
@pytest.fixture()
def login(request):
    print('登录系统')
    token = 'a1b23c'
    def fin1():
        print('退出登录1')
    def fin2():
        print('退出登录2')
    # 执行完测试用例后,将按照注册顺序的相反顺序来调用(先fin2,后fin1)
    request.addfinalizer(fin1)
    request.addfinalizer(fin2)
    return token
 
def test1(login):
    print('in test1: ', login)
    print('测试1')
 
def test2(login):
    print('in test2: ', login)
    print('测试2')

二、使用装饰器@pytest.fixture()的name参数,指定测试固件的名字。

 
import pytest
 
# 给测试固件重新命名为driver,如果不命名,默认login
@pytest.fixture(name = "driver")
def login():
    print('登录系统')
    token = 'a1b23c'
    yield token
    print('退出登录')
 
def test1(driver):
    print('in test1: ', driver)
    print('测试1')
 
def test2(driver):
    print('in test2: ', driver)
    print('测试2')
 

三、通过装饰器@pytest.fixture()的参数scope,设置测试固件的作用域(scope)

1、session > module > class > function

2、代码1

import pytest
 
# scope的值默认function
@pytest.fixture(scope='module')
def log():
    print('开始测试')
    yield
    print('结束测试')
 
@pytest.fixture(scope='function')
def login():
    print('登录系统')
    yield
    print('退出登录')
 
# 注意传参
def test1(log, login):
    print('测试1')
 
def test2(log, login):
    print('测试2')
 
 
执行结果:
setup_demo.py::test1 开始测试
登录系统
测试1
PASSED退出登录
 
setup_demo.py::test2 登录系统
测试2
PASSED退出登录
结束测试

代码2

import pytest
 
@pytest.fixture(scope='module')
def login_module():
    print('开始测试_模块级别')
    yield
    print('结束测试_模块级别')
 
@pytest.fixture(scope='class')
def login_class():
    print('登录系统_类级别')
    yield
    print('退出登录_类级别')
 
@pytest.fixture(scope='function') 
def login_func():
    print('登录系统_函数级别')
    yield
    print('退出登录_函数级别')
 
class TestFoo(object):
 
    def test1(self, login_module, login_class, login_func):
        print('测试1')
 
    def test2(self, login_module, login_class, login_func):
        print('测试2')
 
 
执行结果:
setup_demo.py::TestFoo::test1 开始测试_模块级别
登录系统_类级别
登录系统_函数级别
测试1
PASSED退出登录_函数级别
 
setup_demo.py::TestFoo::test2 登录系统_函数级别
测试2
PASSED退出登录_函数级别
退出登录_类级别
结束测试_模块级别

代码3-----演示session级别的测试固件

①创建一个python包session_demo

②来个test_1.py

def test_1_1(login):
    print('test_1_1')
 
 
def test_1_2(login):
    print('test_1_2')

③来个test_2.py

def test_2_1(login):
    print('test_2_1')
 
 
def test_2_2(login):
    print('test_2_2')

④再来个conftest.py(固定文件名)

import pytest
 
@pytest.fixture(scope='session')
def login():
    print('登录系统')

⑤cd到session_demo,然后pytest -sv .

执行结果
test_1.py::test_1_1 登录系统
test_1_1
PASSED
test_1.py::test_1_2 test_1_2
PASSED
test_2.py::test_2_1 test_2_1
PASSED
test_2.py::test_2_2 test_2_2
PASSED

四、通过装饰器@pytest.fixture()的参数params,实现测试固件的参数化。

代码1

import pytest
 
@pytest.fixture(params=['tom', 'jack'])
def login(request):
    print('%s登录' % request.param)
 
def test1(login):
    print('执行测试1')
 
 
执行结果:
setup_demo.py::test1[tom] tom登录
执行测试1
PASSED
setup_demo.py::test1[jack] jack登录
执行测试1
PASSED

代码2

import pytest
 
@pytest.fixture(params=[('tom', '123'), ('jack', '1234')])
def login(request):
    user = request.param[0]
    passwd = request.param[1]
    print('登录系统: 用户名%s, 密码%s' %(user, passwd))
 
def test1(login):
    print('test 1')
 
 
执行结果:
# 没有指定参数ids,自动生成测试用例的id
conftest.py::test1[login0] 登录系统: 用户名tom, 密码123  # 测试用例的id是login0
test 1
PASSED
conftest.py::test1[login1] 登录系统: 用户名jack, 密码1234  # 测试用例的id是tlogin1
test 1
PASSED

可以通过装饰器@pytest.fixture()的参数ids,设置测试用例的id。

import pytest
 
@pytest.fixture(params=[('tom', '123'), ('jack', '1234')],
                ids=['user_a', 'user_b'])  # 这两个列表里,元素的数目要匹配
def login(request):
    user = request.param[0]
    passwd = request.param[1]
    print('登录系统: 用户名%s, 密码%s' %(user, passwd))
 
def test1(login):
    print('test 1')
 
 
执行结果:
conftest.py::test1[user_a] 登录系统: 用户名tom, 密码123
test 1
PASSED
conftest.py::test1[user_b] 登录系统: 用户名jack, 密码1234
test 1
PASSED

五、在项目里运用起来

 

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
pytest.fixture装饰器pytest测试框架的一个重要特性,用于定义测试用例的共享资源或者测试环境的初始化和清理操作。通过使用fixture装饰器,我们可以在测试用例方便地使用这些共享资源。 fixture装饰器可以应用在函数、类或者模块级别上,它的作用是将被装饰的函数或者方法转变为一个fixture对象。fixture对象可以在测试用例作为参数进行调用,pytest会自动根据参数名匹配相应的fixture对象,并将其传递给测试用例。 fixture装饰器可以接受一些参数来定制其行为,例如scope参数用于指定fixture的作用域,autouse参数用于指定是否自动使用fixture等。 下面是一些常见的fixture用法: 1. 无参数fixture: ```python import pytest @pytest.fixture def setup(): # 初始化操作 yield # 清理操作 def test_example(setup): # 使用setup fixture assert 1 + 1 == 2 ``` 2. 带参数fixture: ```python import pytest @pytest.fixture def setup(request): # 初始化操作 def teardown(): # 清理操作 request.addfinalizer(teardown) def test_example(setup): # 使用setup fixture assert 1 + 1 == 2 ``` 3. fixture作用域: ```python import pytest @pytest.fixture(scope="module") def setup_module(): # 模块级别的初始化操作 yield # 模块级别的清理操作 @pytest.fixture(scope="function") def setup_function(): # 函数级别的初始化操作 yield # 函数级别的清理操作 def test_example(setup_module, setup_function): # 使用setup_module和setup_function fixture assert 1 + 1 == 2 ``` 通过使用fixture装饰器,我们可以更加灵活地管理测试用例的共享资源和测试环境的初始化和清理操作,提高测试用例的可维护性和可重复性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值