【pytest官方文档】解读fixtures - 8. yield和addfinalizer的区别(填坑)

简介: 【pytest官方文档】解读fixtures - 8. yield和addfinalizer的区别(填坑)

上一章中,文末留下了一个坑待填补,疑问是这样的:


目前从官方文档中看到的是


We have to be careful though, because pytest will run that finalizer once it’s been added, 
even if that fixture raises an exception after adding the finalizer.


一旦添加了终结器,pytest便会执行。


但是,当我尝试在setup代码中进行抛错,终结器的代码却并没有执行。


尝试搜索外网暂时也没得到有效的帮助,只能在GitHub上向pytest提了issue了,这里算是埋下一个坑,待后续解决。


一、问题回顾


其实说到底还是我理解的不对,可能当时自己处在疑问中难免就会陷入进死循环,后来在github上经过别人提点方才醒悟。


先来看下当时我尝试演示出上述结果的代码,也就是:setup代码中进行抛错,终结器的代码却并没有执行。


代码分为2部分,一个是fixture函数代码,另一个则是测试用例。代码是不能直接copy出来运行的,是我在项目的用例中


进行改造的,在这里仅仅帮助说明意思。


# content of conftest.py
@pytest.fixture()
def init_data_allot_task(request):
    query_sql = """
    SELECT id FROM `sm_purchase_allot` WHERE `status`!=5
    """
    db = DB()
    data = db.fetch_one(query_sql)
    db.close()
    def demo_finalizer():
        print("running finalizer code...")
    request.addfinalizer(demo_finalizer)
    return data
# content of testcase
...
def test_allot_detail(init_data_allot_task):
    """
    """
    payload = {
          "allotId": init_data_allot_task[0]
        }
    r = requests.post(QA_URL + API_URL, json=payload, headers=HEADER)
    result = r.json()
    assert result["result"] == "ok"
    assert result["errmsg"] == "success"
    assert len(result["row"]["taskListOfPage"]["resultData"]) > 0


最开始我想做的是,在fixture函数中,让代码db = DB()抛出一个mysql连接超时的错误,


然后就能在控制台中看到"running finalizer code..."的输出。


但是我执行后,并没有看到预期的输出,说明setup代码抛错后,addfinalizer代码并没有执行。


最后经过github上朋友指点后,发现还是我自己理解错了。


二、问题解决


还是来看下官方的原文:


We have to be careful though, because pytest will run that finalizer once it’s been added, 
even if that fixture raises an exception after adding the finalizer.


这句话意思其实是说,当finalizer 一旦添加成功后,pytest就会去执行它。就算是fixture函数在添加了finalizer之后

抛出了异常。


按照这样理解的话,那我在fixture函数中的代码就有问题了。因为db = DB()代码在request.addfinalizer(demo_finalizer)


之前就抛错了,那么实际上并没有执行到添加终结器的这行代码,所以终结器都还没添加成功,又怎么会去执行呢?


终于我明白过来了,于是调整了代码顺序,把request.addfinalizer(demo_finalizer)放到前面去,然后再接上fixture的代码:


# content of conftest.py
@pytest.fixture()
def init_data_allot_task(request):
    query_sql = """
    SELECT id FROM `sm_purchase_allot` WHERE `status`!=5 
    """
    def demo_finalizer():
        print("running finalizer code...")
    request.addfinalizer(demo_finalizer)
    print("running setup code...")
    db = DB()
    data = db.fetch_one(query_sql)
    db.close()
    return data


如此来看,我们会先看到"running setup code..."的输出,然后看到mysql抛错,

最后仍然可以看到"running setup code..."的输出。


运行代码验证一下:


1268169-20210307175004469-1726453534.png


这下就对了。

相关文章
|
机器学习/深度学习 Web App开发 数据可视化
过节福利 | MMCV Hook 超全使用方法(下)
在训练过程中,通常有十个关键位点,如下图所示,从训练开始到结束,所有关键位点已用红色标出,共有 10 个。我们可以在这十个位点插入各种逻辑,例如加载模型权重、保存模型权重。而我们将同一类型的逻辑组织成一个 Hook。因此,MMCV 中 Hook 的作用就是训练和验证模型时,在不改变其他代码的前提下,灵活地在不同位点插入定制化的逻辑。
1947 0
过节福利 | MMCV Hook 超全使用方法(下)
|
测试技术
pytest学习和使用23-通俗易懂的聊聊allure常用特性集合及使用方法说明
pytest学习和使用23-通俗易懂的聊聊allure常用特性集合及使用方法说明
134 0
|
测试技术 Python
Pytest Pytest源码分析
Pytest Pytest源码分析
289 0
|
测试技术
pytest学习和使用8-fixture如何实现teardown功能?(yield的使用)
pytest学习和使用8-fixture如何实现teardown功能?(yield的使用)
104 0
|
测试技术 API
【pytest官方文档】解读fixtures - 9. 什么样的fixture结构,用起来最可靠?
【pytest官方文档】解读fixtures - 9. 什么样的fixture结构,用起来最可靠?
【pytest官方文档】解读fixtures - 9. 什么样的fixture结构,用起来最可靠?
|
JSON 测试技术 数据格式
【HttpRunner v3.x】笔记—9.运行testcase的几种方式
【HttpRunner v3.x】笔记—9.运行testcase的几种方式
【HttpRunner v3.x】笔记—9.运行testcase的几种方式
【pytest】(十二)参数化测试用例中的setup和teardown要怎么写?
【pytest】(十二)参数化测试用例中的setup和teardown要怎么写?
【pytest】(十二)参数化测试用例中的setup和teardown要怎么写?
【pytest官方文档】解读fixtures - 11. fixture的执行顺序,3要素详解(长文预警)
【pytest官方文档】解读fixtures - 11. fixture的执行顺序,3要素详解(长文预警)
【pytest官方文档】解读fixtures - 11. fixture的执行顺序,3要素详解(长文预警)
Cypress 好用的用法
大家好,我是阿萨。之前学习了cypress的最基本的用法。可是有些同学还是反馈不会写cypress,怎么办? 今天就列举一些常见的cypress的写法。
291 0
【pytest官方文档】解读fixtures - 2. fixtures的调用方式
【pytest官方文档】解读fixtures - 2. fixtures的调用方式