fixture測驗夾具
一、Fixture介紹
Fixture是pytest精髓所在,就像unittest中的setup和teardown一樣,但相對之下它的功能更加強大和靈活,
二、Fixture的作用
1.做測驗前后的初始化設定,如測驗資料準備,鏈接資料庫,打開瀏覽器等這些操作都可以使用fixture來實作
2.測驗用例的前置條件可以使用fixture實作
3.支持經典的xunit fixture ,像unittest使用的setup和teardown
4.fixture可以實作unittest不能實作的功能,比如unittest中的測驗用例和測驗用例之間是無法傳遞引數和資料的,但是fixture卻可以解決這個問題
三、Fixture定義及呼叫
fixture通過@pytest.fixture()裝飾器裝飾一個函式,那么這個函式就是一個fixture,看個實體:
@pytest.fixture()
def manage_browser():
driver = webdriver.Chrome() # 前置條件
return driver
print("后置條件") # 后置條件
@pytest.mark.fixe
def test_baidu(manage_browser):
driver = manage_browser
driver.get("https://www.baidu.com/")
宣告的測驗夾具函式名稱,作為引數傳入其他函式,即可完成呼叫,可以傳多個fixture,按先后順序執行,

上面的測驗夾具中只用return回傳初始化瀏覽器,return后面的后置條件不會執行,因此需要將return改成yield,后置條件就會被呼叫執行,
Yield是Python中的一個關鍵字,表示生成器,測驗夾具的前置條件遇到yield時回傳一個結果,然后將測驗夾具掛起,轉而去執行測驗用例,最后回來測驗夾具中執行后置條件,Return和yield后面可以不寫任何回傳值,表示空沒有資料回傳,Yield使用示例如下:
import pytest
from selenium import webdriver
@pytest.fixture()
def manage_browser():
# 前置條件
driver = webdriver.Chrome()
yield driver # yield,回傳函式值,可以繼續執行下面的代碼
# 后置條件
driver.quit()
@pytest.mark.fix
def test_baidu(manage_browser):
driver = manage_browser # 這里是引數接收,不能打括號
driver.get("https://www.baidu.com/")
四、Pytest中fixture前置后置條件
Pytest框架中將前置條件,后置條件單獨放在fixture的函式中,所有的用例呼叫測驗夾具的前后置條件,Web自動化的前后置條件如下:
@pytest.fixture()
def manage_browser():
"""初始化瀏覽器"""
driver = webdriver.Chrome()
# 設定隱式等待
driver.implicitly_wait(20)
# 最大化瀏覽器
driver.maximize_window()
# 初始化要用到的頁面
login_page = LoginPage(driver)
# 初始化首頁
index_page = IndexPage(driver)
yield driver, login_page, index_page
# 后置條件
driver.quit()
@pytest.fixture() # 可以同時創建多個測驗夾具
def login():
"""登錄的夾具"""
manage_browser()
pass
要使用測驗夾具,在測驗用例類中的test方法中傳入夾具函式名(例如上面函式的manage_browser),且框架中所有的測驗用例檔案中不需要匯入夾具函式名,是直接使用的,如下代碼:
class TestLogin:
@pytest.mark.parametrize("test_info", test_data_error)
def test_01_login_error(self, test_info, manage_browser):
"""登錄時,手機號為空"""
# 拆開元祖中的引數
driver, login_page, index_page = manage_browser
# 第一步:登錄
login_page.login(test_info["mobile"], test_info["pwd"])
# 獲取實際結果(封裝以后執行的函式或者方法)
actual = login_page.get_error_msg()
# 第二步:獲取預期結果 test_info["expected"]
expected = test_info["expected"]
# 第三步:斷言
# self.assertEqual(expected, actual) unitte中的斷言方式
assert expected == actual
測驗用例類中使用測驗夾具,以及資料傳遞的方式:

注意:Pytest中的fixture測驗夾具單獨放在conftest.py檔案中,且conftest.py檔案需要與pytest啟動檔案放在同一級目錄,

五、Fixture作用域
Unittest框架中setup的作用是每條測驗用例執行之前都會執行一次,setupclass的作用是每個測驗用例類執行之前都會執行一次,
pytest的fixture同樣有這樣的作用域,且使用更廣泛更靈活,
?關鍵代碼:@pytest.fixture(scope='作用范圍'),引數如下:
?? function:默認作用域,每個測驗用例都運行一次
?? class:每個測驗類只執行一次
?? module:每個模塊只執行一次(模塊:一個.py檔案)
?? package:每個python包只執行一次
?? session:整個會話只執行一次,即運行專案時整個程序只執行一次
Fixture后面的括號不加任何引數,就代表默認作用域,與function作用一樣,
示例一:class --每個測驗類只執行一次
import pytest
from selenium import webdriver
test_data = [1, 2, 3]
@pytest.fixture(scope="class")
def manage_browser():
"""初始化瀏覽器"""
driver = webdriver.Chrome()
yield driver
# 后置條件
driver.quit()
class TestHelloWord:
@pytest.mark.parametrize("test_info", test_data)
def test_helloword(self, test_info, manage_browser):
pass
def test_hello(self, manage_browser):
pass
上面的示例TestHelloWord雖然有4條測驗用,但是@pytest.fixture(scope="class") 申明了每個測驗類只執行一次,所以整個程序只打開了一次瀏覽器,如果一個.py檔案中有2個類,就會打開2次瀏覽器,
示例一:module --每個模塊只執行一次
import pytest
from selenium import webdriver
test_data = [1, 2, 3]
@pytest.fixture(scope="module")
def manage_browser():
"""初始化瀏覽器"""
driver = webdriver.Chrome()
yield driver
# 后置條件
driver.quit()
class TestHelloWork:
@pytest.mark.parametrize("test_info", test_data)
def test_helloword(self, test_info, manage_browser):
pass
def test_hello(self, manage_browser):
pass
class TestModule:
@pytest.mark.parametrize("test_info_2", test_data)
def test_module(self, test_info_2, manage_browser):
pass
def test_module2(self, manage_browser):
pass
上面的示例中有兩個類,8條測驗用例,但是測驗夾具作用域設為module --每個模塊只執行一次,所以整個程序只打開一次瀏覽器,
特殊方式:fixture里面有個引數autouse(自動使用的意思),默認是False,當設定為True時,用例就會自動呼叫該fixture功能,這樣的話寫用例時就不用每次都去傳參了,

六、多個測驗夾具
當有多個測驗夾具,可以設定不同的作用域,測驗用例方法后面可以傳需要的測驗夾具,也可以傳入全部測驗夾具
test_data = https://www.cnblogs.com/zdx20/p/[1, 2, 3]
@pytest.fixture(scope="function")
def manage_browser():
"""初始化瀏覽器"""
driver = webdriver.Chrome()
yield driver
print("后置執行")
# 后置條件
driver.quit()
@pytest.fixture(scope="class")
def delete_cookie():
print("delete cookie before")
yield
print("delete cookie after")
class TestHelloWork:
@pytest.mark.parametrize("test_info", test_data)
def test_helloword(self, test_info, manage_browser, delete_cookie):
pass
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/288638.html
標籤:其他
