【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的依然可以正常关闭。

相关文章
|
安全 Java 关系型数据库
单例模式下引发的线程安全问题
单例模式确保类在进程中仅有一个实例,适用于如数据库连接等场景。分为饿汉式与懒汉式:饿汉式在类加载时创建实例,简单但可能浪费资源;懒汉式延迟创建实例,需注意线程安全问题,常采用双重检查锁定(Double-Checked Locking)模式,并使用 `volatile` 关键字避免指令重排序导致的问题。
197 2
单例模式下引发的线程安全问题
|
数据挖掘 调度 开发者
Python并发编程的艺术:掌握线程、进程与协程的同步技巧
并发编程在Python中涵盖线程、进程和协程,用于优化IO操作和响应速度。`threading`模块支持线程,`multiprocessing`处理进程,而`asyncio`则用于协程。线程通过Lock和Condition Objects同步,进程使用Queue和Pipe通信。协程利用异步事件循环避免上下文切换。了解并发模型及同步技术是提升Python应用性能的关键。
298 5
|
设计模式 开发者 Python
探索Python中的异步编程:从基础知识到实践应用
【6月更文挑战第6天】本文旨在深入探讨Python中的异步编程概念,包括其背后的原理、常用的库和框架以及如何在实际项目中应用这些知识。文章将通过具体的代码示例和场景分析,帮助读者理解异步编程在提升程序性能和处理并发任务中的重要性。
|
设计模式 开发者 Python
探索Python中的异步编程:从基础到实战
【6月更文挑战第7天】本文深入探讨了Python中异步编程的概念、工具和实践,旨在帮助读者理解并掌握这一提高程序执行效率和响应能力的重要技术。文章首先介绍了异步编程的基本概念,随后详细讲解了如何使用Python的asyncio库进行异步编程,并通过具体案例展示了异步编程在实际开发中的应用。最后,文章总结了异步编程的最佳实践,为读者提供了一套完整的异步编程解决方案。
|
关系型数据库 MySQL 数据库
探索Python中的异步编程:从基础知识到高级应用
【6月更文挑战第8天】随着技术的进步,异步编程已经成为现代软件开发中不可或缺的一部分。本文将深入探讨Python中的异步编程,包括其基础知识、常用库和框架,以及一些高级应用。我们将通过实例来展示如何有效地使用异步编程来提高程序的性能和响应性。无论你是初学者还是经验丰富的开发者,这篇文章都会为你提供有价值的见解和技巧。
127 2
|
监控 程序员 Python
Python装饰器:深入解析与应用
Python装饰器:深入解析与应用
165 1
|
Python
Python内置函数--必须了解的iter()与next()
Python内置函数--必须了解的iter()与next()
238 0
|
调度 Python Windows
【python】多任务编程之线程、进程知识点详细总结
【python】多任务编程之线程、进程知识点详细总结
141 0
【LeetCode】移动零&&颜色分类&&有序数组的平方&&有效的山脉数组
【LeetCode】移动零&&颜色分类&&有序数组的平方&&有效的山脉数组
【LeetCode】移动零&&颜色分类&&有序数组的平方&&有效的山脉数组
|
XML 存储 自然语言处理
Python3 notes
Python3 notes