您好,登錄后才能下訂單哦!
這篇文章主要介紹“pytest fixtures函數(shù)及測(cè)試函數(shù)的參數(shù)化實(shí)例分析”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“pytest fixtures函數(shù)及測(cè)試函數(shù)的參數(shù)化實(shí)例分析”文章能幫助大家解決問題。
Pytest會(huì)在以下幾個(gè)級(jí)別啟用測(cè)試參數(shù)化:
pytest.fixture(),可以對(duì)fixture函數(shù)進(jìn)行參數(shù)化。
@pytest.mark.parametrize,可以在測(cè)試函數(shù)或類中定義多組參數(shù)和fixture。
pytest_generate_tests,可以自定義參數(shù)化方案或擴(kuò)展。
對(duì)測(cè)試函數(shù)的參數(shù)進(jìn)行參數(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
從代碼里可以看出,在裝飾器里定義了三個(gè)不同的元組。我們把("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
拆開看:
"test_input,expected":這個(gè)字符串里定義了2個(gè)參數(shù),test_input和expected。
("3+5", 8), ("2+4", 6), ("6*9", 42):這里3個(gè)元組,沒個(gè)元組里有2個(gè)元素,依次序分別對(duì)應(yīng)test_input和expected。
3個(gè)元組外層的[]:列表里就是參數(shù)化具體的傳參了,因?yàn)槔锩鎮(zhèn)髁?個(gè)不同的元組,所以測(cè)試函數(shù)test_eval會(huì)分別執(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
運(yùn)行結(jié)果可以看到最后一次失敗了,因?yàn)榈谌芜\(yùn)行測(cè)試函數(shù)取的參數(shù)是 ("6*9", 42),54不等于42,所以斷言失敗。
在參數(shù)化中標(biāo)記單個(gè)測(cè)試實(shí)例,比如之前提到過的mark.xfail,這個(gè)可以標(biāo)記測(cè)試函數(shù)為失敗。那么在參數(shù)化中,如果想讓其中的某個(gè)參數(shù)運(yùn)行
的時(shí)候測(cè)試失敗,就可以這樣用:
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
運(yùn)行一下:
test_module1.py [100%] ======================== 2 passed, 1 xfailed in 0.05s =========================..x
如果在測(cè)試函數(shù)上加了多個(gè)參數(shù)化裝飾器,那么得到的參數(shù)組合是一個(gè)笛卡爾積:
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)該會(huì)組合成4組數(shù)據(jù)x=0/y=2, x=1/y=2, x=0/y=3, 和x=1/y=3,測(cè)試函數(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 ==============================
如果有些場(chǎng)景需要?jiǎng)討B(tài)的確定參數(shù)或者fixture的使用范圍,那么可以使用pytest_generate_tests這個(gè)鉤子函數(shù),該函數(shù)會(huì)在收集測(cè)試函數(shù)時(shí)候被調(diào)用。
通過傳入的metafunc對(duì)象,可以檢查請(qǐng)求測(cè)試函數(shù)的上下文,還可以進(jìn)一步的調(diào)用metafunc.parameterize()來實(shí)現(xiàn)參數(shù)化。
舉例,有個(gè)測(cè)試函數(shù)需要接受輸入的字符串作為參數(shù),而且通過pytest命令行獲取到,那么就要編寫一個(gè)獲取參數(shù)的fixture函數(shù)來給測(cè)試函數(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)在用命令行方式來運(yùn)行這個(gè)測(cè)試函數(shù):
pytest -q --stringinput="hello" --stringinput="world" test_strings.py
會(huì)運(yùn)行2次。
D:\PycharmProjects\wms-api\interface\demo>pytest -q --stringinput="hello" --stringinput="world" test_strings.py .. [100%] 2 passed in 0.01s
再換個(gè)輸入?yún)?shù),讓測(cè)試函數(shù)失?。?/p>
pytest -q --stringinput="!" test_strings.py
FAILED test_strings.py::test_valid_string[!] - AssertionError: assert False1 failed in 0.04s
如果沒有字符串輸入,那么測(cè)試函數(shù)它將被跳過。因?yàn)閙etafunc.parameterize()被調(diào)用時(shí),傳過去的是一個(gè)列表:
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ù)集進(jìn)行多次參數(shù)化,這些參數(shù)集上的所有參數(shù)名稱都不能重復(fù),否則將會(huì)報(bào)錯(cuò)。
關(guān)于“pytest fixtures函數(shù)及測(cè)試函數(shù)的參數(shù)化實(shí)例分析”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。