1. 程式人生 > 實用技巧 >Pytest系列(9) - 引數化@pytest.mark.parametrize

Pytest系列(9) - 引數化@pytest.mark.parametrize

一、前言

pytest允許在多個級別啟用測試引數化:

  • pytest.fixture() 允許fixture有引數化功能(後面講解)
  • @pytest.mark.parametrize 允許在測試函式或類中定義多組引數和fixtures
  • pytest_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 自動化中的開發場景,比如是一個登入框

  1. 你肯定需要測試賬號空、密碼空、賬號密碼都為空、賬號不存在、密碼錯誤、賬號密碼正確
    等情況
  2. 這些用例的區別就在於輸入的測試資料和對應的互動結果
  3. 所以我們可以只寫一條登入測試用例,然後把多組測試資料和期望結果引數化,節省很多程式碼量

五、原始碼分析

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