在上一章中,文末留下了一個(gè)坑待填補(bǔ),疑問是這樣的:
目前從官方文檔中看到的是
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.
一旦添加了終結(jié)器,pytest便會(huì)執(zhí)行。
但是,當(dāng)我嘗試在setup代碼中進(jìn)行拋錯(cuò),終結(jié)器的代碼卻并沒有執(zhí)行。
嘗試搜索外網(wǎng)暫時(shí)也沒得到有效的幫助,只能在GitHub上向pytest提了issue了,這里算是埋下一個(gè)坑,待后續(xù)解決。
一、問題回顧
其實(shí)說到底還是我理解的不對(duì),可能當(dāng)時(shí)自己處在疑問中難免就會(huì)陷入進(jìn)死循環(huán),后來在github上經(jīng)過別人提點(diǎn)方才醒悟。
先來看下當(dāng)時(shí)我嘗試演示出上述結(jié)果的代碼,也就是:setup代碼中進(jìn)行拋錯(cuò),終結(jié)器的代碼卻并沒有執(zhí)行。
代碼分為2部分,一個(gè)是fixture函數(shù)代碼,另一個(gè)則是測(cè)試用例。代碼是不能直接copy出來運(yùn)行的,是我在項(xiàng)目的用例中
進(jìn)行改造的,在這里僅僅幫助說明意思。
# 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函數(shù)中,讓代碼db = DB() 拋出一個(gè)mysql連接超時(shí)的錯(cuò)誤,
然后就能在控制臺(tái)中看到"running finalizer code..." 的輸出。
但是我執(zhí)行后,并沒有看到預(yù)期的輸出,說明setup代碼 拋錯(cuò)后,addfinalizer代碼 并沒有執(zhí)行。
最后經(jīng)過github上朋友指點(diǎn)后,發(fā)現(xiàn)還是我自己理解錯(cuò)了。
二、問題解決
還是來看下官方的原文:
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.
這句話意思其實(shí)是說,當(dāng)finalizer 一旦添加成功后,pytest就會(huì)去執(zhí)行它。就算是fixture函數(shù)在添加了finalizer 之后
拋出了異常。
按照這樣理解的話,那我在fixture函數(shù)中的代碼就有問題了。因?yàn)?code>db = DB()代碼在request.addfinalizer(demo_finalizer)
之前就拋錯(cuò)了,那么實(shí)際上并沒有執(zhí)行到添加終結(jié)器的這行代碼,所以終結(jié)器都還沒添加成功,又怎么會(huì)去執(zhí)行呢?
終于我明白過來了,于是調(diào)整了代碼順序,把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
如此來看,我們會(huì)先看到"running setup code..." 的輸出,然后看到mysql拋錯(cuò),
最后仍然可以看到"running setup code..." 的輸出。
運(yùn)行代碼驗(yàn)證一下:
這下就對(duì)了。
|