【pytest】teardown里的yield和addfinalizer

简介: 【pytest】teardown里的yield和addfinalizer

一、yield


再来简单回顾下pytest里的setUp和tearDown的用法,我们可以看到,下方代码里有三个case用例,分别是test_开头。


而在demo_fixture函数里,有一个yield关键字。那么在yield之前的代码,会在case之前执行,yield之后的代码,则会在case运行结束后执行。


#yield_finalizer_demo.py
import pytest
@pytest.fixture()
def demo_fixture():
    print("\n这个fixture在每个case前执行一次")
    yield
    print("\n在每个case完成后执行的teardown")
def test_01(demo_fixture):
    print("\n===执行了case: test_01===")
def test_02(demo_fixture):
    print("\n===执行了case: test_02===")
def test_03(demo_fixture):
    print("\n===执行了case: test_03===")


好了,现在我3个case都传入这个demo_fixture,运行一下,看下效果。这3个红色框中标出的分别就是每一个case执行前后的代码输出,符合我们的预期。


1268169-20200608103425059-945484083.png


二、addfinalizer


现在,我们再来看addfinalizer,这里我姑且叫它终结器。在用法上,addfinalizer跟yield是不同的,需要你去注册作为终结器使用的函数。


这里还是用上方的代码去修改,去掉yield关键字,增加一个新的函数demo_finalizer,并且注册成终结函数:


import pytest
@pytest.fixture()
def demo_fixture(request):
    print("\n这个fixture在每个case前执行一次")
    def demo_finalizer():
        print("\n在每个case完成后执行的teardown")
    #注册demo_finalizer为终结函数    
    request.addfinalizer(demo_finalizer)
def test_01(demo_fixture):
    print("\n===执行了case: test_01===")
def test_02(demo_fixture):
    print("\n===执行了case: test_02===")
def test_03(demo_fixture):
    print("\n===执行了case: test_03===")


接下来,运行一下,可以看到结果与使用yield的时候一致。


1268169-20200608103500048-196243388.png


三、yield与addfinalizer的区别


那么,除了在使用上的区别之外,yield与addfinalizer还有什么不同呢?


1. addfinalizer可以注册多个终结函数。


import pytest
@pytest.fixture()
def demo_fixture(request):
    print("\n这个fixture在每个case前执行一次")
    def demo_finalizer():
        print("\n在每个case完成后执行的teardown")
    def demo_finalizer2():
        print("\n在每个case完成后执行的teardown2")
    def demo_finalizer3():
        print("\n在每个case完成后执行的teardown3")
    #注册demo_finalizer为终结函数    
    request.addfinalizer(demo_finalizer)
    request.addfinalizer(demo_finalizer2)
    request.addfinalizer(demo_finalizer3)
def test_01(demo_fixture):
    print("\n===执行了case: test_01===")
def test_02(demo_fixture):
    print("\n===执行了case: test_02===")
def test_03(demo_fixture):
    print("\n===执行了case: test_03===")


在代码里增加demo_finalizer2,demo_finalizer3,这2个终结函数。运行一下:


1268169-20200608103548858-1100992181.png


可以看到,注册的3个函数都被执行了,但是要注意的是执行顺序,与注册的顺序相反


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


这里接官方文档上的例子说明一下:


@pytest.fixture
def equipments(request):
    r = []
    for port in ('C1', 'C3', 'C28'):
    equip = connect(port)
    request.addfinalizer(equip.disconnect)
    r.append(equip)
    return r


比如,C1,C3,C28这3个端口连接,如果C28这个端口失败了,这时候会抛出一个连接异常,但是在执行teardown关闭连接的时候,C1和C3的依然可以正常关闭。

相关文章
|
缓存 测试技术
31-pytest-内置fixture之cache使用
31-pytest-内置fixture之cache使用
31-pytest-内置fixture之cache使用
|
测试技术
32-pytest-内置fixture之request使用
32-pytest-内置fixture之request使用
|
测试技术 Python
Pytest前后置以及fixture实战部分
Pytest前后置以及fixture实战部分
43 0
|
测试技术 Python
pytest--fixture
pytest--fixture
|
Web App开发 测试技术
10-pytest-parametrize中使用fixture
10-pytest-parametrize中使用fixture
|
测试技术
03-pytest-测试用例setup和teardown
03-pytest-测试用例setup和teardown