您好,登錄后才能下訂單哦!
這篇文章主要介紹了pytest中fixture函數有什么用,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
與python自帶的unitest測試框架中的setup、teardown類似,pytest提供了fixture函數用以在測試執行前和執行后進行必要的準備和清理工作。但是相對來說又比setup、teardown好用。
命名方式靈活,不局限于setup和teardown這幾個命名
conftest.py 配置里可以實現數據共享,不需要import就能自動找到一些配置
scope="module" 可以實現多個.py跨文件共享前置, 每一個.py文件調用一次
scope="session" 以實現多個.py跨文件使用一個session來完成多個用例
通過將fixture聲明為參數名,測試用例函數可以請求fixture。fixture修飾器來標記固定的工廠函數,在其他函數,模塊,類或整個工程調用它時會被激活并優先執行,通常會被用于完成預置處理和重復操作。
# 定義的夾具函數,使用裝飾器pytest.fixture @pytest.fixture def my_fruit(): print("login:用戶執行登錄操作") # 使用夾具函數的測試用例 def test_my_fruit_in_basket(my_fruit): print("hello world") if __name__ == '__main__': pytest.main(['test_login.py::test_my_fruit_in_basket', '-s']) #執行結果: collected 1 item test_login.py login: 用戶執行登錄操作 hello world . ============================== 1 passed in 0.02s ==========================
做測試前后的初始化設置,如測試數據準備,鏈接數據庫,打開瀏覽器等這些操作都可以使用fixture來實現。
測試用例的前置條件可以使用fixture實現 。
支持經典的xunit fixture ,像unittest使用的setup和teardown。
fixture可以實現unittest不能實現的功能,比如unittest中的測試用例和測試用例之間是無法傳遞參數和數據的,但是fixture卻可以解決這個問題。
Fixture名字作為測試用例的參數
可以直接使用fixture名稱作為輸入參數(是個典型的高階函數),在這種情況下,fixture函數返回的fixture實例將被注入,最終在測試用例執行前執行這個裝飾過的函數。如下列代碼,①將返回值傳遞給測試用例,②通過函數入參方式,可以傳入多個fixture函數
import pytest @pytest.fixture def first_entry(): return "a" @pytest.fixture def order(first_entry): return [first_entry] def test_string(order): order.append("b") assert order == ["a", "b"], "斷言執行失敗" if __name__ == '__main__': pytest.main(['test_login.py::test_string', '-s'])
使用@pytest.mark.usefixtures('fixture')裝飾器
每個函數或者類前使用@pytest.mark.usefixtures('fixture')裝飾器進行裝飾。
import pytest @pytest.fixture def my_fruit(): print("login:用戶執行登錄操作") # 被夾具函數裝飾的測試用例 @pytest.mark.usefixtures("my_fruit") def test_my_fruit_in_basket(): print("hello world") if __name__ == '__main__': pytest.main(['test_login.py', '-s', '-q']) # 執行結果 login:用戶執行登錄操作 hello world . 1 passed in 0.01s
使用autouse參數
指定fixture的參數autouse=True這樣模塊內的每個測試用例會自動調用fixture。
import pytest @pytest.fixture(autouse=True) def my_fruit(): print("login:用戶執行登錄操作") # 被夾具函數裝飾的測試用例 def test_my_fruit_in_basket(): print("hello world") if __name__ == '__main__': pytest.main(['test_login.py', '-s', '-q'])
備注: 如果fixture有返回值,那么usefixture以及autouse就無法獲取到返回值,這個是裝飾器usefixture與用例直接傳fixture參數的區別。 因此最常用的是通過參數傳遞的方法。
Fixture中的scope的參數,控制Fixture函數的作用范圍
scope = ‘function' 測試函數維度,默認范圍,則在測試結束時銷毀fixture。
scope = ‘class' 測試類維度,在class中最后一次測試的拆卸過程中,夾具被破壞。
scope = ‘module' 測試文件維度,在模塊中最后一次測試的拆卸過程中,夾具被破壞。
scope = ‘session' 測試會話維度,夾具在測試會話結束時被銷毀。
fixture函數的返回值:return 和 yield 和 addfinalizer終結函數
return:
通過下面的代碼,我們已經發現可以通過測試用例函數傳入參數的形式,直接使用fixture函數的返回值,這個相對來說比較簡單。
import pytest @pytest.fixture def first_entry(): return "a" @pytest.fixture def order(first_entry): return [first_entry] def test_string(order): order.append("b") assert order == ["a", "b"], "斷言執行失敗" if __name__ == '__main__': pytest.main(['test_login.py::test_string', '-s'])
yield:
yeild也是一種函數的返回值類型,是函數上下文管理器,使用yield被調fixture函數執行遇到yield會停止執行,接著執行調用的函數,調用的函數執行完后會繼續執行fixture函數yield關鍵后面的代碼。因此利用fixture函數,我們可以說pytest集合了setup、teardown,既做了初始化,又做了后置的清理工作。
import pytest from emaillib import Email, MailAdminClient @pytest.fixture def mail_admin(): return MailAdminClient() # 配置發送者的fixture函數 @pytest.fixture def sending_user(mail_admin): user = mail_admin.create_user() #setup:創建發件人 yield user # 返回發件人 admin_client.delete_user(user) #teardown:刪除發件人 # 配置收件人的fixture函數 @pytest.fixture def receiving_user(mail_admin): user = mail_admin.create_user() #setup:創建收件人 yield user #返回收件人 admin_client.delete_user(user) #teardown:刪除收件人 def test_email_received(sending_user, receiving_user, email): email = Email(subject="Hey!", body="How's it going?") sending_user.send_email(email, receiving_user) assert email in receiving_user.inbox
翻譯下面代碼,在調用Entry_into_index前,啟動APP,遇到yield關鍵字,中止fixture函數調用,執行調用函數Entry_into_index內容,在Entry_into_index函數調用后,執行yield函數后的driver.close_app(),關閉APP。
@pytest.fixture(scope='session') def startApp_fixture(start_app): driver = start_app res = lp(driver).get_agree_info() try: assert res == "同意" except Exception as e: log.error("啟動APP失敗") log.exception(e) raise e else: lp(driver).click_agree() lp(driver).click_next_step() lp(driver).click_alert() lp(driver).click_pass() # 創建首頁 index_page = indexPage(driver) yield index_page, driver # 后置條件 time.sleep(3) driver.close_app() # 調用fixture函數 @pytest.fixture(scope='session') def Entry_into_index(startApp_fixture) index_page = startApp_fixture()[0] driver = startApp_fixture()[1]
工廠作為固定裝置:可以使用閉包,通過外部去調用函數里面函數。
工廠固定裝置原因:
上面已經說過,調用fixture函數A可以通過用fixture名稱作為調用函數B參數,在這種情況下,fixture函數返回的fixture實例將被注入,最終在測試用例B執行前執行這個裝飾過的函數def B(A):pass。但是有個問題在給測試用例添加裝飾函數時,傳入的參數是fixture函數的函數名,如果需要給fixture函數添加參數時,是不可以用下面形式,代碼會直接報錯。原因是測試用例傳入參數為fixture函數名,如果fixture函數名添加(參數)后,表現形式為add(params)實際為函數調用。可參考高階函數與裝飾器,并無此用法。
解決方式使用閉包,如下圖代碼:make_customer_record函數返回的是內部函數_make_customer_record(夾具不直接返回數據,而是返回一個生成數據的函數),注意此處未加(),非函數調用,因此在測試用例中customer_1 = make_customer_record("Lisa")此處可拆解為兩部分,customer_1 = make_customer_record的結果為_make_customer_record對象 ,加上("Lisa") 實際是對調_make_customer_record函數進行調用:函數名+(參數),以達到可以傳參的目的。
@pytest.fixture def make_customer_record(): def _make_customer_record(name): return {"name": name, "orders": []} return _make_customer_record #注意此處不加(),非函數調用 def test_customer_records(make_customer_record): customer_1 = make_customer_record("Lisa")
感謝你能夠認真閱讀完這篇文章,希望小編分享的“pytest中fixture函數有什么用”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。