pytest?fixtures函數(shù)及測試函數(shù)的參數(shù)化解讀
pytest fixtures測試函數(shù)參數(shù)化
Pytest會在以下幾個級別啟用測試參數(shù)化:
- pytest.fixture(),可以對fixture函數(shù)進行參數(shù)化。
- @pytest.mark.parametrize,可以在測試函數(shù)或類中定義多組參數(shù)和fixture。
- pytest_generate_tests,可以自定義參數(shù)化方案或擴展。
一、@pytest.mark.parametrize:參數(shù)化測試函數(shù)
1. 常規(guī)用法
對測試函數(shù)的參數(shù)進行參數(shù)化,直接使用內(nèi)置的裝飾器pytest.mark.parameterized即可。
import pytest @pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)]) def test_eval(test_input, expected): assert eval(test_input) == expected
從代碼里可以看出,在裝飾器里定義了三個不同的元組。我們把("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
拆開看:
- "test_input,expected":這個字符串里定義了2個參數(shù),test_input和expected。
- ("3+5", 8), ("2+4", 6), ("6*9", 42):這里3個元組,沒個元組里有2個元素,依次序分別對應(yīng)test_input和expected。
- 3個元組外層的[]:列表里就是參數(shù)化具體的傳參了,因為里面?zhèn)髁?個不同的元組,所以測試函數(shù)test_eval會分別執(zhí)行3次。
============================= test session starts ============================= platform win32 -- Python 3.9.4, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 rootdir: D:\PycharmProjects\wms-api\interface, configfile: pytest.inicollected 3 items test_module1.py ..F demo\test_module1.py:3 (test_eval[6*9-42]) 54 != 42 Expected :42 Actual :54 <Click to see difference> test_input = '6*9', expected = 42 @pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)]) def test_eval(test_input, expected): > assert eval(test_input) == expected E AssertionError: assert 54 == 42 E + where 54 = eval('6*9') test_module1.py:6: AssertionError
運行結(jié)果可以看到最后一次失敗了,因為第三次運行測試函數(shù)取的參數(shù)是 ("6*9", 42),54不等于42,所以斷言失敗。
2. 在參數(shù)化中標(biāo)記單個測試實例
在參數(shù)化中標(biāo)記單個測試實例,比如之前提到過的mark.xfail,這個可以標(biāo)記測試函數(shù)為失敗。那么在參數(shù)化中,如果想讓其中的某個參數(shù)運行
的時候測試失敗,就可以這樣用:
import pytest @pytest.mark.parametrize( "test_input,expected", [("3+5", 8), ("2+4", 6), pytest.param("6*9", 42, marks=pytest.mark.xfail)], ) def test_eval(test_input, expected): assert eval(test_input) == expected
運行一下:
test_module1.py [100%] ======================== 2 passed, 1 xfailed in 0.05s =========================..x
3. 多個參數(shù)化組合,笛卡爾積
如果在測試函數(shù)上加了多個參數(shù)化裝飾器,那么得到的參數(shù)組合是一個笛卡爾積:
import pytest @pytest.mark.parametrize("x", [0, 1]) @pytest.mark.parametrize("y", [2, 3]) def test_foo(x, y): print("\nx:", x) print("y:", y)
應(yīng)該會組合成4組數(shù)據(jù)x=0/y=2, x=1/y=2, x=0/y=3, 和x=1/y=3,測試函數(shù)執(zhí)行4次:
test_module1.py . x: 0 y: 2 . x: 1 y: 2 . x: 0 y: 3 . x: 1 y: 3 [100%] ============================== 4 passed in 0.01s ==============================
二、用鉤子函數(shù)pytest_generate_tests example拓展
如果有些場景需要動態(tài)的確定參數(shù)或者fixture的使用范圍,那么可以使用pytest_generate_tests這個鉤子函數(shù),該函數(shù)會在收集測試函數(shù)時候被調(diào)用。
通過傳入的metafunc對象,可以檢查請求測試函數(shù)的上下文,還可以進一步的調(diào)用metafunc.parameterize()來實現(xiàn)參數(shù)化。
舉例,有個測試函數(shù)需要接受輸入的字符串作為參數(shù),而且通過pytest命令行獲取到,那么就要編寫一個獲取參數(shù)的fixture函數(shù)來給測試函數(shù)調(diào)用。
# content of test_strings.py def test_valid_string(stringinput): assert stringinput.isalpha()
新建conftest.py文件,fixture函數(shù)寫在這里:
# content of conftest.py def pytest_addoption(parser): parser.addoption( "--stringinput", action="append", default=[], help="list of stringinputs to pass to test functions", ) def pytest_generate_tests(metafunc): if "stringinput" in metafunc.fixturenames: metafunc.parametrize("stringinput", metafunc.config.getoption("stringinput"))
現(xiàn)在用命令行方式來運行這個測試函數(shù):
pytest -q --stringinput="hello" --stringinput="world" test_strings.py
會運行2次。
D:\PycharmProjects\wms-api\interface\demo>pytest -q --stringinput="hello" --stringinput="world" test_strings.py .. [100%] 2 passed in 0.01s
再換個輸入?yún)?shù),讓測試函數(shù)失?。?/p>
pytest -q --stringinput="!" test_strings.py
FAILED test_strings.py::test_valid_string[!] - AssertionError: assert False1 failed in 0.04s
如果沒有字符串輸入,那么測試函數(shù)它將被跳過。因為metafunc.parameterize()被調(diào)用時,傳過去的是一個列表:
pytest -q -rs test_strings.py
SKIPPED [1] test_strings.py: got empty parameter set ['stringinput'], function test_valid_string at $REGENDOC_TMPDIR/test_strings.py:2 1 skipped in 0.12s
注意,在調(diào)用metafunc時, 如果使用不同的參數(shù)集進行多次參數(shù)化,這些參數(shù)集上的所有參數(shù)名稱都不能重復(fù),否則將會報錯。
總結(jié)
文中講到的3種用法,實際應(yīng)用中第一種最常見,第二種次之,至于第三種,可以作為一些用法啟發(fā),更多關(guān)于pytest fixtures測試函數(shù)參數(shù)化的資料請關(guān)注腳本之家其它相關(guān)文章!
- pytest解讀fixtures中yield與addfinalizer區(qū)別
- pytest解讀fixtures之Teardown處理yield和addfinalizer方案
- pytest官方文檔解讀fixtures的調(diào)用方式
- pytest官方文檔解讀fixtures
- pytest官方文檔解讀fixtures的autouse
- pytest解讀一次請求多個fixtures及多次請求
- pytest官方文檔解讀fixtures調(diào)用fixtures及fixture復(fù)用性
- pytest解讀fixture有效性及跨文件共享fixtures
- pytest fixtures裝飾器的使用和如何控制用例的執(zhí)行順序
- Pytest中Fixtures的高級用法
相關(guān)文章
Python增量循環(huán)刪除MySQL表數(shù)據(jù)的方法
這篇文章主要介紹了Python增量循環(huán)刪除MySQL表數(shù)據(jù)的相關(guān)資料,本文介紹的非常詳細(xì),具有參考借鑒價值,需要的朋友可以參考下2016-09-09python用requests實現(xiàn)http請求代碼實例
這篇文章主要介紹了python用requests實現(xiàn)http請求過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-10-10Python繪制數(shù)據(jù)動態(tài)圖的方法詳解
這篇文章主要為大家詳細(xì)介紹了如何利用Python語言繪制好看的數(shù)據(jù)動態(tài)圖,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起動手嘗試一下2022-07-07詳解使用python繪制混淆矩陣(confusion_matrix)
這篇文章主要介紹了詳解使用python繪制混淆矩陣(confusion_matrix),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07在Python中封裝GObject模塊進行圖形化程序編程的教程
這篇文章主要介紹了在Python中封裝GObject模塊進行圖形化程序編程的教程,本文來自于IBM官方網(wǎng)站技術(shù)文檔,需要的朋友可以參考下2015-04-04python時間與Unix時間戳相互轉(zhuǎn)換方法詳解
這篇文章主要介紹了python時間與Unix時間戳相互轉(zhuǎn)換方法詳解,需要的朋友可以參考下2020-02-02