pytest使用yield关键字实现teardown_xxx的功能和request.addfinalizer()注册清理函数

上一篇讲到fixture通过scope参数控制前置setup的范围,既然有setup作为用例之前前的操作,用例执行完之后那肯定也有teardown操作。
使用fixture的teardown操作并不需要独立的函数,用yield关键字可实现teardown操作

#使用yield关键字实现teardown_xxx的功能

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

# 通过python解释器执行需要以下代码
if __name__ == '__main__':
    pytest.main(["-s", "test_yieldDemo.py"])

执行结果:

"C:\Program Files\Python37\python.exe" E:/PycharmProjects/api_pytest/testsfixture/test_yieldDemo.py
============================= test session starts =============================
platform win32 -- Python 3.7.1, pytest-6.1.1, py-1.9.0, pluggy-0.13.1
rootdir: E:\PycharmProjects\api_pytest, configfile: pytest.ini
plugins: allure-pytest-2.8.18
collected 2 items

test_yieldDemo.py 登录系统
执行测试 test1:  a1b23c
测试1
.退出登录
登录系统
执行测试 test2:  a1b23c
测试2
.退出登录


============================== 2 passed in 0.08s ==============================

Process finished with exit code 0
说明:yield

yieldfixture中起到了唤起teardown的作用,同时也可以和return一样返回值。
yieldreturn的区别是:
return执行完成,该函数终止;
yield在返回结束后,后续的代码仍可执行。

import pytest

@pytest.fixture(scope="module")
def open():
    print("打开浏览器,并且打开百度首页")
    yield
    print("执行teardown!")
    print("最后关闭浏览器")

def test_s1(open):
    print("用例1:搜索python-1")

def test_s2(open):
    print("用例2:搜索python-2")

def test_s3(open):
    print("用例3:搜索python-3")

if __name__ == "__main__":
    pytest.main(["-s", "test_fixturemodule2.py"])

执行结果:

test_fixturemodule2.py 打开浏览器,并且打开百度首页
用例1:搜索python-1
.用例2:搜索python-2
.用例3:搜索python-3
.执行teardown!
最后关闭浏览器

request.addfinalizer()注册清理函数

1.除了yield可以实现teardown,我们也可以通过request.addfinalizer()的方式实现“teardown”。它和yield相比不同的是:无论是固件的“setup”部分是否出现异常或断言失败,它都会执行(关于这一点我还没有演示出来,感觉setup中如果有异常addfinalizer依然不会执行,希望大佬指导);此外它还支持传入多个函数。
#上例子:我们在固件中传入request参数;又在固件中定义了一个内置函数;最后将定义的内置函数添加到request的addfinalizer中。


import pytest
 
# login函数是一个测试固件,相当于实现了setup_xxx&teardown_xxx的功能
@pytest.fixture()
# 声明使用request测试固件
def login(request):
    print('登录系统')
    token = 'a1b23c'
    # 定义一个清理函数, 清理函数向相当于teardown_xxx
    #assert 1 == 2
    def fin():
        print('退出登录')
        assert 1==2 #teardown部分报异常也不影响,request.addfinalizer(fin)还是会执行这个函数
    # 注册一个清理函数
    request.addfinalizer(fin)
    # 注册完清理函数后,如果在测试固件里抛出异常,清理函数照常执行
    return token
#@pytest.mark.xfail()
def test_1(login):
    print('in test1: ', login)
    print('测试1')

#@pytest.mark.xfail()
def test_2(login):
    print('in test2: ', login)
    print('测试2')

if __name__ == "__main__":
    pytest.main(["-s", "test_addfinalizer.py"])

执行结果:

"C:\Program Files\Python37\python.exe" E:/PycharmProjects/api_pytest/testsfixture/test_addfinalizer.py
============================= test session starts =============================
platform win32 -- Python 3.7.1, pytest-6.1.1, py-1.9.0, pluggy-0.13.1
rootdir: E:\PycharmProjects\api_pytest, configfile: pytest.ini
plugins: allure-pytest-2.8.18
collected 2 items

test_addfinalizer.py 登录系统
in test1:  a1b23c
测试1
.退出登录
E登录系统
in test2:  a1b23c
测试2
.退出登录
E

=================================== ERRORS ====================================
_________________________ ERROR at teardown of test_1 _________________________

    def fin():
        print('退出登录')
>       assert 1==2 #teardown部分报异常也不影响,request.addfinalizer(fin)还是会执行这个函数
E       assert 1 == 2

test_addfinalizer.py:17: AssertionError
_________________________ ERROR at teardown of test_2 _________________________

    def fin():
        print('退出登录')
>       assert 1==2 #teardown部分报异常也不影响,request.addfinalizer(fin)还是会执行这个函数
E       assert 1 == 2

test_addfinalizer.py:17: AssertionError
=========================== short test summary info ===========================
ERROR test_addfinalizer.py::test_1 - assert 1 == 2
ERROR test_addfinalizer.py::test_2 - assert 1 == 2
========================= 2 passed, 2 errors in 0.92s =========================

Process finished with exit code 0

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值