『德不孤』Pytest框架 — 15、Pytest參數化

1、Pytest參數化說明

軟體測試中,輸入相應值,檢查期望值,是常見測試方法。

在自動化測試中,一個測試用例對應一個測試點,通常一組測試數據是無法完全覆蓋測試範圍的,所以需要參數化來傳遞多組數據。

Unittest單元測試框架使用DDT進行數據驅動測試,Pytest是使用@pytest.mark.parametrize裝飾器來實現數據驅動測試的。

2、Pytest參數化方式

Pytest有三種傳參方式,主要用到前兩種

  • @pytest.mark.parametrize()裝飾器方式進行參數化。(常用)
  • pytest.fixture()方式進行參數化,fixture裝飾的函數可以作為參數傳入其他函數。
  • conftest.py文件中存放參數化函數,可作用於模組內的所有測試用例。

這裡只說明第一種參數化方式。

3、parametrize裝飾器參數說明

parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)

說明:

  • argnames:參數名,使用逗號分隔的字元串,或列表或元祖,表示一個或多個參數名。(常用參數)
  • argvalues:參數值,類型可以是列表,元祖,字典列表,字典元祖,有多個值用例就會執行多少次。(常用參數)
  • indirect:當indirect=True時,若傳入的argnames(參數)是Fixture函數名,此時Fixture函數名將是一個可執行的函數,Fixture裝飾器返回的數據作為argnames的參數,最終結果會存入request.param中。
    當indirect=False時,Fixture函數只作為一個參數名,給測試收集階段調用。
    說明:結合Fixture裝飾器的內容一起看,就會明白上面說的是什麼意思。(這個參數不常用,默認即可)
  • ids:字元串列表,可以理解成給前面的argvalues參數起別名,別名個數和數據的值相同。
  • scope:如果指定,則表示參數的使用範圍。
    作用域用於按參數實例對測試進行分組。(待理解)
    它還將覆蓋任何Fixture函數定義的範圍。
    允許使用測試上下文或配置設置動態範圍。(待理解)
    (這個參數不常用,默認即可)

4、Pytest參數化(單個參數)

示例:

"""
1.學習目標
    掌握pytest中參數化方法
2.操作步驟
    parametrize(argnames,argvalues)
        argnames 參數名稱
        argvalues 參數值
    @pytest.mark.parametrize()
3.單個參數使用
    argnames 一定和測試用例中的參數名保持一致
    argvalues 是一個列表格式

"""
import pytest

# 有幾個數據,用例就執行幾次。
data = ["13800138000", "13800138001", "13800138002"]

@pytest.mark.parametrize("phonenum", data)
def test_login(phonenum):
    # test_login函數的參數phonenum,要和parametrize定義的參數phonenum一致。
    print(f"輸入電話號碼{phonenum}")

if __name__ == '__main__':
    pytest.main()

"""
執行結果:

test_01.py::test_login[13800138000] 輸入電話號碼13800138000
PASSED
test_01.py::test_login[13800138001] 輸入電話號碼13800138001
PASSED
test_01.py::test_login[13800138002] 輸入電話號碼13800138002
PASSED

我們可以看到用例執行了3次。
"""

5、Pytest參數化(多個參數)

示例:

"""
1.學習目標
    掌握pytest中參數化方法
2.操作步驟
    parametrize(argnames,argvalues)
        argnames 參數名稱
        argvalues 參數值
    @pytest.mark.parametrize()
3.多個參數使用
    argnames:字元串格式,各個參數之間逗號隔開
    argvalues: [(),(),()],列表嵌套元組,元組中元素的個數和參數個數一致

"""
import pytest

# 有幾個數據,用例就執行幾次。
data = [("13800138000", 1234), ("13800138001", 2345), ("13800138002", 3456)]

# "phonenum,code"參數名個數,要和列表中對象的參數個數一致。
@pytest.mark.parametrize("phonenum,code", data)
def test_login(phonenum, code):
    print(f"輸入電話號碼{phonenum}")
    print(f"輸入驗證碼{code}")
    assert phonenum == "13800138000"


if __name__ == '__main__':
    pytest.main()

"""
執行結果:

test_01.py::test_login[13800138000-1234] 輸入電話號碼13800138000
輸入驗證碼1234
PASSED
test_01.py::test_login[13800138001-2345] 輸入電話號碼13800138001
輸入驗證碼2345
FAILED
test_01.py::test_login[13800138002-3456] 輸入電話號碼13800138002
輸入驗證碼3456
FAILED
"""

6、ids參數說明

示例:

"""
import pytest

# 有幾個數據,用例就執行幾次。
data = [("13800138000", 1234), ("13800138001", 2345), ("13800138002", 3456)]


# "phonenum,code"參數名個數,要和列表中對象的參數個數一致。
@pytest.mark.parametrize("phonenum,code", data, ids=['333', '666', '999'])
def test_login(phonenum, code):
    print(f"輸入電話號碼{phonenum}")
    print(f"輸入驗證碼{code}")



if __name__ == '__main__':
    pytest.main()

"""
執行結果:

test_01.py::test_login[333] 輸入電話號碼13800138000
輸入驗證碼1234
PASSED
test_01.py::test_login[666] 輸入電話號碼13800138001
輸入驗證碼2345
PASSED
test_01.py::test_login[999] 輸入電話號碼13800138002
輸入驗證碼3456
PASSED

請和上面的例子對比[]號中的資訊,就是在ids參數中定義的資訊。

"""