Pytest系列(9) - 引數化@pytest.mark.parametrize
阿新 • • 發佈:2020-11-20
一、前言
pytest允許在多個級別啟用測試引數化:
pytest.fixture()
允許fixture有引數化功能(後面講解)@pytest.mark.parametrize
允許在測試函式或類中定義多組引數和fixturespytest_generate_tests
允許定義自定義引數化方案或擴充套件(拓展)
二、引數化的場景
只有測試資料和期望結果不一樣,但操作步驟是一樣的測試用例可以用上引數化;
可以看看下面的例子
三、未引數化的程式碼
def test_1(): assert 3 + 5 == 9 def test_2(): assert 2 + 4 == 6 def test_3(): assert 6 * 9 == 42
可以看到,三個用例都是加法然後斷言某個值,重複寫三個類似的用例有點冗餘
四、利用引數化優化之後的程式碼
@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
def test_eval(test_input, expected):
print(f"測試資料{test_input},期望結果{expected}")
assert eval(test_input) == expected
4.1 實際 web ui 自動化中的開發場景,比如是一個登入框
- 你肯定需要測試賬號空、密碼空、賬號密碼都為空、賬號不存在、密碼錯誤、賬號密碼正確
- 這些用例的區別就在於輸入的測試資料和對應的互動結果
- 所以我們可以只寫一條登入測試用例,然後把多組測試資料和期望結果引數化,節省很多程式碼量
五、原始碼分析
def parametrize(self,argnames, argvalues, indirect=False, ids=None, scope=None):
5.1 argnames
原始碼解析:a comma-separated string denoting one or more argument names, or a list/tuple of argument strings.
含義:引數名字
格式:字串"arg1,arg2,arg3"【需要用逗號分隔】
示例
@pytest.mark.parametrize(["name", "pwd"], [("yy1", "123"), ("yy2", "123")])
@pytest.mark.parametrize(("name", "pwd"), [("yy1", "123"), ("yy2", "123")])
@pytest.mark.parametrize("name,pwd", [("yy1", "123"), ("yy2", "123")])
5.2 argvalues
原始碼解析:
- The list of argvalues determines how often a test is invoked with different argument values.
- If only one argname was specified argvalues is a list of values.
【只有一個引數,則是值列表】
- If N argnames were specified, argvalues must be a list of N-tuples, where each tuple-element specifies a value for its respective argname.
【如果有多個引數,則用元組來存每一組值】
含義:引數值列表
格式:必須是列表,如:[ val1,val2,val3 ]
如果只有一個引數,裡面則是值的列表如:@pytest.mark.parametrize("username", ["yy", "yy2", "yy3"])
如果有多個引數例,則需要用元組來存放值,一個元組對應一組引數的值,如:@pytest.mark.parametrize("name,pwd", [("yy1", "123"), ("yy2", "123"), ("yy3", "123")])
備註:雖然原始碼說需要list包含tuple,但我試了下,tuple包含list,list包含list也是可以的........
5.3 ids
含義:用例的ID
格式:傳一個字串列表
作用:可以標識每一個測試用例,自定義測試資料結果的顯示,為了增加可讀性
強調:
ids的長度需要與測試資料列表的長度一致
5.4 indirect
作用:如果設定成True,則把傳進來的引數當函式執行
,而不是一個引數(下一篇博文即講解)
六、裝飾測試類
@pytest.mark.parametrize('a, b, expect', data_1)
class TestParametrize:
def test_parametrize_1(self, a, b, expect):
print('\n測試函式11111 測試資料為\n{}-{}'.format(a, b))
assert a + b == expect
def test_parametrize_2(self, a, b, expect):
print('\n測試函式22222 測試資料為\n{}-{}'.format(a, b))
assert a + b == expect