[跟著官方文檔學(xué)pytest][四][學(xué)習(xí)筆記](méi)
1.關(guān)于fixtures
pytest fixtures被設(shè)計(jì)為顯式,模塊化和可擴(kuò)展的。
1.1.什么是fixtures
在測(cè)試中,fixtures為測(cè)試提供了定義、可靠和一致的上下文。這可能包括環(huán)境(例如,配置了已知參數(shù)的數(shù)據(jù)庫(kù))或內(nèi)容(例如數(shù)據(jù)集)。
Fixture定義了構(gòu)成測(cè)試排列階段的步驟和數(shù)據(jù)(參照Anatomy of a test)。在pytest中,它們是你定義的用于此目的的函數(shù)。它們可用于定義測(cè)試的行為階段;這是設(shè)計(jì)更復(fù)雜測(cè)試的強(qiáng)大技術(shù)。
由于fixtures設(shè)置的服務(wù)、狀態(tài)或其他操作環(huán)境由測(cè)試函數(shù)通過(guò)參數(shù)訪問(wèn)。對(duì)于測(cè)試函數(shù)使用的每個(gè)fixture,測(cè)試函數(shù)的定義中通常都有一個(gè)參數(shù)(以fixture命名)。
我們可以告訴pytest,一個(gè)特定的功能是一個(gè)用@pytest.fixture修飾的。下面是一個(gè)簡(jiǎn)單例子:
import pytest class Fruit: def __init__(self, name): self.name = name def __eq__(self, other): return self.name == other.name @pytest.fixture def my_fruit(): return Fruit("apple") @pytest.fixture def fruit_basket(my_fruit): return [Fruit("banana"), my_fruit] def test_my_fruit_in_basket(my_fruit, fruit_basket): assert my_fruit in fruit_basket
測(cè)試也不必局限于單個(gè)fixture。可以根據(jù)需要依賴任意數(shù)量的固定fixtures,并且fixtures可以使用其他fixtures。這就是pytest的fixture系統(tǒng)真正亮眼的地方。
1.2.改進(jìn)xUnit-style的setup/teardown功能
fixtures對(duì)經(jīng)典xUnit-style的setup/teardown功能有如下改進(jìn):
fixtures據(jù)偶顯示名稱,并通過(guò)從測(cè)試函數(shù),模塊,類或整個(gè)項(xiàng)目中聲明它們使用來(lái)激活。
fixtures以模塊化方式實(shí)現(xiàn),因?yàn)槊總€(gè)fixtures名稱都會(huì)觸發(fā)一個(gè)fixture功能,這個(gè)fixture功能也可以使用其他fixtures。
fixture管理從簡(jiǎn)單的單元擴(kuò)展到復(fù)雜的功能測(cè)試,允許根據(jù)配置和組件選項(xiàng)參數(shù)化fixtures和測(cè)試,或跨功能、類、模塊或整個(gè)測(cè)試會(huì)話范圍重用fixtures。
無(wú)論使用多少fixtures,teardown邏輯可以輕松安全地管理,而無(wú)需手動(dòng)自動(dòng)仔細(xì)處理錯(cuò)誤或微觀管理添加清理步驟的順序。
1.3.Fixture錯(cuò)誤
pytest盡最大努力將給定測(cè)試的所有fixtures按線性順序排序,以便可以看到哪個(gè)fixture先發(fā)生。如果較早的fixture有問(wèn)題引發(fā)異常,pytest將停止執(zhí)行該測(cè)試的fixtures,并將測(cè)試標(biāo)記為錯(cuò)誤。
但是當(dāng)測(cè)試被標(biāo)記為錯(cuò)誤時(shí),并不意味著測(cè)試失敗。只是意味著無(wú)法嘗試測(cè)試,因?yàn)樗蕾嚨氖挛镏淮嬖趩?wèn)題。
這就是為什么為給定測(cè)試刪除盡可能多的不必要的依賴項(xiàng)是個(gè)好主意原因之一。這樣不相關(guān)事物中的問(wèn)題就不會(huì)導(dǎo)致我們對(duì)可能存在或可能沒(méi)有問(wèn)題的內(nèi)容有不完整的了解。
以下示例幫我們理解fixture
import pytest @pytest.fixture def order(): return [] @pytest.fixture def append_first(order): order.append(1) @pytest.fixture def append_second(order, append_first): order.extend([2]) @pytest.fixture(autouse=True) def append_third(order, append_second): order += [3] def test_order(order): assert order == [1, 2, 3]
如果,無(wú)論出于何種原因,order.append(1)有一個(gè)錯(cuò)誤并且引發(fā)了異常,將無(wú)法知道order.extend([2])或order+=[3]是否會(huì)有問(wèn)題。在append_first拋出異常后,pytest不會(huì)再為test_order運(yùn)行任何fixtures,甚至不會(huì)嘗試運(yùn)行test_order本身。唯一會(huì)運(yùn)行的東西將是order和append_first。
為了引發(fā)異常將order.append(1)改為order.append(),會(huì)發(fā)生如下圖異常:
1.4.分享測(cè)試數(shù)據(jù)
如果要使文件中的測(cè)試數(shù)據(jù)可用于測(cè)試,一個(gè)好方法是將這些數(shù)據(jù)加載到fixtures中以供測(cè)試使用。這利用了pytest的自動(dòng)緩存機(jī)制。
另一種好方法是在tests文件夾中添加數(shù)據(jù)文件。還有一些社區(qū)插件可以幫助管理測(cè)試的這一方面,例如pytest-datadir和pytest-datafiles。
1.5.Fixture清理的說(shuō)明
pytest不對(duì)SIGTERM和SIGQUIT信號(hào)進(jìn)行任何特殊處理(SIGINT由Python運(yùn)行時(shí)通過(guò)鍵盤(pán)中斷自然處理),因此管理外部資源的fixtures在Python進(jìn)程終止時(shí)(通過(guò)這些信號(hào))需要清除,可能會(huì)泄漏資源。
pytest不處理這些信號(hào)來(lái)執(zhí)行fixture清理的原因是信號(hào)處理程序是全局的,更改它們可能會(huì)干擾正在執(zhí)行的代碼。
Python
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。