關于自動化測試框架pytest的Fixture固件
什么是固件
Fixture 翻譯成中文即是固件的意思。它其實就是一些函數(shù),會在執(zhí)行測試方法/測試函數(shù)之前(或之后)加載運行它們,常見的如接口用例在請求接口前數(shù)據(jù)庫的初始連接,和請求之后關閉數(shù)據(jù)庫的操作。
我們之前在APP UI自動化系列中已經(jīng)介紹過 unittest 的相關測試固件,如setup
、teardown
等。而 pytest 中提供了功能更加豐富的Fixture
,用于實現(xiàn)setup
、teardown
功能。
定義方式
使用@pytest.fixture()
進行定義,簡單示例如下:
import pytest @pytest.fixture() def before(): print("連接數(shù)據(jù)庫")
調用方式
調用單個fixture函數(shù)
- 方式一,使用fixture函數(shù)名作為參數(shù)
import pytest @pytest.fixture() def before(): print("連接數(shù)據(jù)庫") # 調用before def test_01(before): print("執(zhí)行test_01")
- 方式二,使用
@pytest.mark.usefixtures('fixture函數(shù)名')
裝飾器
import pytest @pytest.fixture() def before(): print("連接數(shù)據(jù)庫") # 調用before @pytest.mark.usefixtures('before') def test_01(): print("執(zhí)行test_01")
- 方式三,使用
autouse
參數(shù)自動執(zhí)行fixture
函數(shù)
import pytest # fixture函數(shù)定義的時候使用autouse參數(shù),作用域范圍內的測試用例會自動調用該fixture函數(shù) @pytest.fixture(autouse=True) def before(): print("連接數(shù)據(jù)庫") # 自動調用before def test_01(): print("執(zhí)行test_01")
三種方式調用后的結果都如下:
我們可以看到,先執(zhí)行了fixture
函數(shù),再執(zhí)行測試函數(shù)。
調用多個fixture函數(shù)
import pytest @pytest.fixture() def before(): print("連接數(shù)據(jù)庫") @pytest.fixture() def before_s(): print("初始化數(shù)據(jù)") def test_01(before, before_s): print("執(zhí)行test_01")
調用多個 fixture 函數(shù)時,由前至后依次執(zhí)行,所以test_01()
調用時先執(zhí)行before
,再執(zhí)行before_s
。
對fixture函數(shù)重命名
定義fixture
函數(shù)時,可以利用name
參數(shù)進行重命名,方便用于調用,示例如下:
import pytest @pytest.fixture(name='db') def connect_order_db(): print("連接數(shù)據(jù)庫") def test_01(db): print("執(zhí)行test_01")
使用fixture傳遞測試數(shù)據(jù)
在執(zhí)行完fixture
函數(shù)后,有時需要將該fixture
中得到到某些數(shù)據(jù)傳遞給測試函數(shù)/測試方法,用于后續(xù)的執(zhí)行。
fixture
中提供普通傳遞和參數(shù)化傳遞兩種數(shù)據(jù)傳遞方式。
普通傳遞
示例如下:
import pytest @pytest.fixture() def before(): print("連接數(shù)據(jù)庫") return "連接成功!" def test_01(before): print("執(zhí)行test_01") assert before == "連接成功!"
注意,如果自定義的fixture
函數(shù)有返回值,需要使用上面說的方式一調用才能獲取fixture
函數(shù)的返回值并傳入測試函數(shù)中,方式二就無法獲取返回值。
參數(shù)化傳遞
對fixture
函數(shù)進行參數(shù)化時,需要使用參數(shù)params
,并且需要傳入?yún)?shù)request
,簡單示例如下:
import pytest test_params = [1, 2, 0] @pytest.fixture(params=test_params) def before(request): result = request.param return result def test_02(before): print("執(zhí)行test_02") assert before if __name__ == '__main__': pytest.main()
執(zhí)行結果:
可以看到,因為所調用的fixture函數(shù)進行了參數(shù)化,雖然只有一個測試函數(shù)但執(zhí)行了3次。
conftest.py
上面我們舉的例子都是把fixture函數(shù)放在測試用例模塊里面,但如果很多測試模塊需要引用同一個fixture函數(shù)怎么辦,這是時候就需要把它放在命名為conftest
的模塊里,這樣同級或以下目錄中的測試用例便能調用這些自定義的fixture函數(shù)。
例如,有如下目錄:
├─testcase │ │ │ ├─test_module_01 │ │ test_case_1.py │ │ test_case_2.py │ │ │ ├─test_module_02 │ │ test_case_3.py
test_module_01 中的test_case_1.py
與test_case_2.py
都需要調用同一個 fixture 函數(shù),那么我們只需要在 test_module_01 中新建conftest.py
并編寫這個fixture
函數(shù)即可,示例如下:
├─testcase │ │ │ ├─test_module_01 │ │ conftest.py │ │ test_case_1.py │ │ test_case_2.py │ │ │ ├─test_module_02 │ │ test_case_3.py
conftest.py
:
import pytest @pytest.fixture(autouse=True) def before(): print("連接數(shù)據(jù)庫")
test_case_1.py
:
def test_01(): print("執(zhí)行test_01")
test_case_2.py
:
def test_02(): print("執(zhí)行test_02")
這樣,執(zhí)行這兩個模塊的測試用例時會自動先去調用conftest.py
中的before()
函數(shù)。
假設 test_module_02 中的 test_case_3.py 也需要調用這個before()
函數(shù),那么這個時候我們就需要在上一層即 testcase 中新建conftest.py
并編寫這個before()
函數(shù),才能在 test_case_3.py 中調用,如下:
├─testcase │ │ conftest.py │ │ │ ├─test_module_01 │ │ conftest.py │ │ test_case_1.py │ │ test_case_2.py │ │ │ ├─test_module_02 │ │ test_case_3.py
conftest.py
只作用于同級
或以下
目錄中的測試模塊,且需要注意,當以下
層級中存在了另一個conftest.py
,那么以下層級將由另一個conftest.py
文件接管。
作用域
pytest 的 fixture 作用域分session
、module
、class
、function
四個級別。在定義 fixture 函數(shù)的時候通過scope
參數(shù)指定作用范圍,默認為function
。
session
,每次會話執(zhí)行一次module
,每個測試模塊執(zhí)行一次class
,每個測試類執(zhí)行一次function
,每個測試方法執(zhí)行一次
注意,對于單獨定義的測試函數(shù),class、function 都會起作用,可以從下列示例中看出來。
測試目錄結構如下:
├─apiAutoTest │ │ run.py │ │ │ ├─testcase │ │ │ conftest.py │ │ │ │ │ ├─test_module_02 │ │ │ │ conftest.py │ │ │ │ test_case_3.py │ │ │ │ test_case_4.py
其中conftest.py
代碼如下:
import pytest @pytest.fixture(scope="session", autouse=True) def session_fixture(): print("這是一個作用于session的fixture") @pytest.fixture(scope="module", autouse=True) def module_fixture(): print("這是一個作用于module的fixture") @pytest.fixture(scope="class", autouse=True) def class_fixture(): print("這是一個作用于class的fixture") @pytest.fixture(scope="function", autouse=True) def function_fixture(): print("這是一個作用于function的fixture")
test_case_3.py
代碼如下:
import pytest class TestOrder: def test_a(self): print("test_a") def test_b(self): print("test_b") def test_c(): print("test_c")
test_case_4.py
代碼如下:
def test_e(): print("test_e")
run.py
代碼如下:
import pytest if __name__ == '__main__': pytest.main(["-s"])
運行run.py
,結果如下:
collected 4 items testcase\test_module_02\test_case_3.py 這是一個作用于session的fixture 這是一個作用于module的fixture 這是一個作用于class的fixture 這是一個作用于function的fixture test_a .這是一個作用于function的fixture test_b .這是一個作用于class的fixture 這是一個作用于function的fixture test_c . testcase\test_module_02\test_case_4.py 這是一個作用于module的fixture 這是一個作用于class的fixture 這是一個作用于function的fixture test_e . ============================== 4 passed in 0.04s ==============================
從結果可以看出來:
- 作用于
session
的fixture函數(shù)只在所有測試用例執(zhí)行之前調用了一次 - 作用于
module
的fixture函數(shù)在每個測試模塊執(zhí)行之前調用了一次 - 作用于
class
的fixture函數(shù)在每個測試類執(zhí)行之前調用了一次 - 作用于
function
的fixture函數(shù)在每個測試方法/測試函數(shù)執(zhí)行之前調用了一次
注意,在定義的測試函數(shù)(如test_c()
、test_e()
)執(zhí)行之前也會調用scope=class的fixture函數(shù)。
總結
與 unittest 框架比較,pytest 中的Fixture
更加豐富,可擴展性更高。
Fixture
還有很多更加優(yōu)雅的用法用于自動化測試項目中,本文只是以最簡單的示例進行說明。
到此這篇關于關于自動化測試框架pytest的Fixture固件的文章就介紹到這了,更多相關自動化測試Fixture固件內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
把大數(shù)據(jù)數(shù)字口語化(python與js)兩種實現(xiàn)
當出現(xiàn)萬以上的整型數(shù)字時,經(jīng)常要把它們口語化比較直觀。下面分享兩段代碼,python與js的2013-02-02Python 中如何使用 setLevel() 設置日志級別
這篇文章主要介紹了在 Python 中使用setLevel() 設置日志級別,Python 提供了一個單獨的日志記錄模塊作為其標準庫的一部分,以簡化日志記錄,本文將討論日志記錄 setLevel 及其在 Python 中的工作方式,需要的朋友可以參考下2023-07-07python中的selenium實現(xiàn)自動向下滾動頁面并指定最大滑動距離
這篇文章主要介紹了python中的selenium實現(xiàn)自動向下滾動頁面并指定最大滑動距離,下文有關selenium的資料介紹有一定的參考價值,需要的小伙伴可以參考一下2022-02-02Python執(zhí)行外部命令subprocess的使用詳解
subeprocess模塊是python自帶的模塊,無需安裝,主要用來取代一些就的模塊或方法,本文通過實例代碼給大家分享Python執(zhí)行外部命令subprocess及使用方法,感興趣的朋友跟隨小編一起看看吧2021-05-05