網站首頁 編程語言 正文
pytest fixtures測試函數參數化
Pytest會在以下幾個級別啟用測試參數化:
- pytest.fixture(),可以對fixture函數進行參數化。
- @pytest.mark.parametrize,可以在測試函數或類中定義多組參數和fixture。
- pytest_generate_tests,可以自定義參數化方案或擴展。
一、@pytest.mark.parametrize:參數化測試函數
1. 常規用法
對測試函數的參數進行參數化,直接使用內置的裝飾器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個參數,test_input和expected。
- ("3+5", 8), ("2+4", 6), ("6*9", 42):這里3個元組,沒個元組里有2個元素,依次序分別對應test_input和expected。
- 3個元組外層的[]:列表里就是參數化具體的傳參了,因為里面傳了3個不同的元組,所以測試函數test_eval會分別執行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
運行結果可以看到最后一次失敗了,因為第三次運行測試函數取的參數是 ("6*9", 42),54不等于42,所以斷言失敗。
2. 在參數化中標記單個測試實例
在參數化中標記單個測試實例,比如之前提到過的mark.xfail,這個可以標記測試函數為失敗。那么在參數化中,如果想讓其中的某個參數運行
的時候測試失敗,就可以這樣用:
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. 多個參數化組合,笛卡爾積
如果在測試函數上加了多個參數化裝飾器,那么得到的參數組合是一個笛卡爾積:
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)
應該會組合成4組數據x=0/y=2, x=1/y=2, x=0/y=3, 和x=1/y=3,測試函數執行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 ==============================
二、用鉤子函數pytest_generate_tests example拓展
如果有些場景需要動態的確定參數或者fixture的使用范圍,那么可以使用pytest_generate_tests這個鉤子函數,該函數會在收集測試函數時候被調用。
通過傳入的metafunc對象,可以檢查請求測試函數的上下文,還可以進一步的調用metafunc.parameterize()來實現參數化。
舉例,有個測試函數需要接受輸入的字符串作為參數,而且通過pytest命令行獲取到,那么就要編寫一個獲取參數的fixture函數來給測試函數調用。
# content of test_strings.py
def test_valid_string(stringinput):
assert stringinput.isalpha()
新建conftest.py文件,fixture函數寫在這里:
# 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"))
現在用命令行方式來運行這個測試函數:
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
再換個輸入參數,讓測試函數失?。?/p>
pytest -q --stringinput="!" test_strings.py
FAILED test_strings.py::test_valid_string[!] - AssertionError: assert False1 failed in 0.04s
如果沒有字符串輸入,那么測試函數它將被跳過。因為metafunc.parameterize()被調用時,傳過去的是一個列表:
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
注意,在調用metafunc時, 如果使用不同的參數集進行多次參數化,這些參數集上的所有參數名稱都不能重復,否則將會報錯。
總結
原文鏈接:https://blog.csdn.net/wessonlan/article/details/124813092
相關推薦
- 2023-05-15 shell?提取文件名和目錄名的方法實現_linux shell
- 2022-05-31 利用python庫matplotlib繪制不同的圖表_python
- 2022-04-11 關于Git提交代碼到遠程倉庫出現:“error: failed to push some refs
- 2022-06-12 Android?Flutter利用貝塞爾曲線畫一個小海豚_Android
- 2022-10-24 React中的生命周期和子組件_React
- 2023-05-22 解決The?Network?Adapter?could?not?establish?the?conn
- 2022-03-28 通過numba模塊給Python代碼提速的方法詳解_python
- 2022-09-29 LyScript實現內存交換與差異對比的方法詳解_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支