fixture是確定是否掌握Pytest高級用法的一種方式,類似unittest中setup/teardown,但是比它們要強大、靈活很多,它的優(yōu)勢是可以 跨文件共享绪抛。
-有獨立的命名资铡,并通過聲明它們從測試函數(shù)、模塊幢码、類或整個項目中的使用來激活笤休。
-按模塊化的方式實現(xiàn),每個fixture都可以互相調(diào)用症副。
-fixture可以實現(xiàn)unittest不能實現(xiàn)的功能店雅,比如unittest中的測試用例和測試用例之間是無法傳遞參數(shù)和數(shù)據(jù)的,但是fixture卻可以解決這個問題贞铣。
-fixture的范圍從簡單的單元擴展到復雜的功能測試闹啦,允許根據(jù)配置和組件選項對fixture和測試用例進行參數(shù)化。
使用方法
1辕坝、定義fixture跟定義普通函數(shù)差不多窍奋,唯一區(qū)別就是在函數(shù)上加個裝飾器@pytest.fixture(),fixture命名不要用test_開頭,跟用例區(qū)分開琳袄。
2江场、 fixture裝飾器里的scope有四個級別的參數(shù)〗讯海“function(不寫則默認這個)”址否、“class”、“module”碎紊、“session”
3佑附、 fixture可以有返回值,如果沒有return矮慕,默認會是None;用例調(diào)用fixture的返回值帮匾,就是直接把fixture的函數(shù)名稱作為參數(shù)傳入
4、fixture可以返回一個元組痴鳄、列表或字典
5瘟斜、 測試用例可傳單個、多個fixture參數(shù)痪寻,需要執(zhí)行順序
6螺句、 fixture與fixture間也可相互調(diào)用
應(yīng)用場景
1、fixture:作為參數(shù)傳遞使用
fixture的名字直接作為測試用例的參數(shù)橡类,用例調(diào)用fixture的返回值蛇尚,直接將fixture的函數(shù)名稱當做變量名稱。 如果用例需要用到多個fixture的返回數(shù)據(jù)顾画,fixture也可以返回一個元祖取劫,list或字典,然后從里面取出對應(yīng)數(shù)據(jù)
import pytest
@pytest.fixture()
def before1():
print("=====打印前置操作1=====")
name = 'happy'
return name
@pytest.fixture()
def before2():
print("=====打印前置操作2=====")
psw = 123456
return psw
def test_login(before1, before2):
name = before1
psw = before2
print(name,psw)
assert name == "happy"
assert psw == 123456
import pytest
@pytest.fixture()
def user():
print("=====打印裝飾器函數(shù)=====")
username = 'happy'
psw = 123456
return username, psw
def test_login(user):
print(user)
assert user[0] == "happy"
assert user[1] == 123456
@pytest.fixture()
def func():
obj = {"a": 1, "b": 2, "c": 3}
return obj
def test_01(func):
print("\nin test_01")
for key, value in func.items():
print(key, value)
2研侣、提供靈活的類似setup和teardown功能
Pytest的fixture另一個強大的功能就是在函數(shù)執(zhí)行前后增加操作谱邪,類似setup和teardown操作,但是比setup和
teardown的操作更加靈活庶诡。 具體使用方式是同樣定義一個函數(shù)惦银,然后用裝飾器標記為fixture,然后在此函數(shù)中使用一個yield語句末誓,yield語句之
前的就會在測試用例之前使用扯俱,yield之后的語句就會在測試用例執(zhí)行完成之后再執(zhí)行。如果需要傳遞參數(shù)喇澡,則在yield之后加對應(yīng)參數(shù)
import pytest
@pytest.fixture()
def func():
print("run before testcase......")
yield
print("run after testcase......")
def test_01(func):
print("in test_01")
def test_02():
print("in test_02")
def test_03(func):
print("in test_03")
import pytest
@pytest.fixture
def db():
print("in fixture db before testcase......")
yield
print("in fixture db after testcase......")
@pytest.fixture
def redis():
print("in fixture redis before testcase......")
yield
print("in fixture redis after testcase......")
def test_01(db):
print("in test_01")
def test_02(redis,db):
print("in test_02")
import pytest
@pytest.fixture
def driver_fixture():
"""實現(xiàn)瀏覽器的打開和關(guān)閉"""
driver = webdriver.Chrome()
yield driver
driver.quit()
def search(driver_fixture)
driver = driver_fixture
driver.findXXXXxXXXXX
3迅栅、利用pytest.mark.usefixtures疊加,如果一個方法或者一個class用例想要同時調(diào)用多個fixture晴玖,可以使用@pytest.mark.usefixture()進行疊加库继。注意疊
加順序箩艺,先執(zhí)行的放底層,后執(zhí)行的放上層宪萄。
4艺谆、fixture自動設(shè)置autouse=True,當用例很多的時候拜英,每次都傳這個參數(shù)静汤,會很麻煩。fixture里面有個參數(shù)autouse居凶,默認是False沒開啟的虫给,可以設(shè) 置為True開啟自動使用fixture功能,這樣用例就不用每次都去傳參了侠碧,autouse設(shè)置為True抹估,自動調(diào)用fixture功能 。
fixture作用域
1弄兜、function:每一個函數(shù)或方法都會調(diào)用药蜻,默認是function,可以寫成@pytest.fixture(scope='function')或@pytest.fixture()
2替饿、class:每一個類調(diào)用一次语泽,一個類中可以有多個方法。
測試類中只要有一個用例使用了class級別的fixture视卢,則整個類的所有用例執(zhí)行之前都會執(zhí)行fixture定義的操作踱卵,測試類所有用例執(zhí)行之后也要運行fixture定義的操作;在類外的函數(shù)中去使用class級別的fixture据过,則此時在測試類外每個測試用例中惋砂,fixture跟function級別的 fixture作用是一致的,即在類外的函數(shù)中引用了fixture绳锅,則在此函數(shù)之前和之后同樣去執(zhí)行fixture定義的對應(yīng)的 操作西饵。
3、 module:每一個.py文件調(diào)用一次榨呆,該文件內(nèi)又有多個function和class
當fixture的scope定義為module時,只要當前文件中有一個測試用例使用了fixture庸队,不管 這個用例是在類外积蜻,還是在類中,都會在當前文件(模塊)的所有測試用例執(zhí)行之前去執(zhí)行fixture定義的行為以及 當前文件的所有用例結(jié)束之后同樣去執(zhí)行fixture定義的對應(yīng)操作
4彻消、 session:是多個文件調(diào)用一次竿拆,可以跨.py文件調(diào)用(通常這個級別會結(jié)合conftest.py文件使用),如登錄token的邏輯可以用session級別
指在當前目錄下的所有用例之前和之后執(zhí)行fixture對應(yīng)的操作宾尚。
使用方式:在指定目錄下創(chuàng)建conftest.py文件丙笋,然后在conftest.py文件中定義fixture方法谢澈,將scope指定為session ,此時在當前目錄下只要有一個用例使用了此fixture御板,則就會在當前目錄下所有用例之前和之后會執(zhí)行fixture定義 的對應(yīng)的操作狞尔。