Pytest學習筆記8-引數化

RockChe發表於2021-07-02

前言

我們在實際自動化測試中,某些測試用例是無法通過一組測試資料來達到驗證效果的,所以需要通過引數化來傳遞多組資料

在unittest中,我們可以使用第三方庫parameterized來對資料進行引數化,從而實現資料驅動測試

而在pytest中,也提供了功能強大的@pytest.mark.parametrize裝飾器來實現資料引數化

Pytest引數化的方式

pytest有三種傳參方式

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

@pytest.mark.parametrize實現引數化

裝飾測試類

當裝飾器 @pytest.mark.parametrize 裝飾測試類時,會將資料集合傳遞給類的所有測試用例方法

舉個?

import pytest

# 定義測試資料
data1 = [
    (1, 2, 3),
    (4, 5, 9)
]


# 定義add方法
def add(a, b):
    return a + b


# 新增parametrize裝飾器
@pytest.mark.parametrize('a, b, expect', data1)
class TestParametrize(object):

    def test_parametrize_1(self, a, b, expect):
        print(f'\n測試用例1資料為{a}-{b},結果為{expect}')
        assert add(a, b) == expect

    def test_parametrize_2(self, a, b, expect):
        print(f'\n測試用例2資料為{a}-{b},結果為{expect}')
        assert add(a, b) == expect

執行結果如下

image-20210701160856783

裝飾測試函式

單個資料

當測試用例只需要一個引數時,我們使用列表存放測試資料,例如定義一個列表

data = [1,2]

使用@pytest.mark.parametrize裝飾器時,第一個引數使用變數a接收列表中的每個元素,第二個引數傳遞儲存資料的列表

在測試用例中使用同名的變數a接收測試資料,列表有多少個元素就會生成並執行多少個測試用例

上程式碼

import pytest

data = [1, 2 , 3]


@pytest.mark.parametrize('a', data)
def test_parametrize(a):
    print(f'\n被載入測試資料為{a}')

執行結果如下

image-20210701162111100

一組資料

當測試用例需要多個資料時,我們可以使用巢狀序列(巢狀元組&巢狀列表)的列表來存放測試資料

裝飾器@pytest.mark.parametrize()可以使用單個變數接收資料,也可以使用多個變數接收,同樣,測試用例函式也需要與其保持一致

當使用單個變數接收時,測試資料傳遞到測試函式內部時為列表中的每一個元素或者小列表,需要使用索引的方式取得每個資料

當使用多個變數接收資料時,那麼每個變數分別接收小列表或元組中的每個元素

列表巢狀多少個列表或元組,測生成多少條測試用例

上程式碼

import pytest

data = [
    [1, 2, 3],
    [4, 5, 9]
]


@pytest.mark.parametrize('a, b, expect', data)
def test_parametrize_1(a, b, expect):  
# 當使用多個變數接收資料時,那麼每個變數分別接收小列表或元組中的每個元素
    print(f'\n測試資料為{a},{b},{expect}')
    actual = a + b
    assert actual == expect


@pytest.mark.parametrize('value', data)
def test_parametrize_2(value):
當使用單個變數接收時,測試資料傳遞到測試函式內部時為列表中的每一個元素或者小列表,需要使用索引的方式取得每個資料
    print(f'\n測試資料為{value}')
    actual = value[0] + value[1]
    assert actual == value[2]

執行結果如下

image-20210701163343794

組合資料

一個測試函式還可以同時被多個引數化裝飾器裝飾,多個裝飾器中的資料會進行交叉組合的方式傳遞給測試函式,進而生成n*n個測試用例,這也為我們的測試設計時提供了方便

上程式碼

import pytest

data_1 = [1, 2]
data_2 = [3, 4, 5]


@pytest.mark.parametrize('a', data_1)
@pytest.mark.parametrize('b', data_2)
def test_parametrize_1(a, b):
    print(f'\n測試資料為{a},{b}')

執行結果如下

image-20210701164355094

標記用例

當我們不想執行某組測試資料時,我們可以標記skip或skipif

當我們預期某組資料會執行失敗時,我們可以標記為xfail

上程式碼

import pytest

data1 = [
    [1, 2, 3],
    pytest.param(3, 4, 8, marks=pytest.mark.xfail),
    pytest.param(3, 4, 7, marks=pytest.mark.skip)
]


def add(a, b):
    return a + b


@pytest.mark.parametrize("a,b,expected", data1)
def test_mark(a, b, expected):
    print(f'測試資料為{a},{b},結果為{expected}')
    assert add(a, b) == expected

執行結果如下

image-20210701233107572

巢狀字典

資料列表中也可以使用字典型別的資料

上程式碼

import pytest

data_1 = (
    {
        'user': 1,
        'pwd': 2
     },
    {
        'user': 3,
        'pwd': 4
    }
)


@pytest.mark.parametrize('dic', data_1)
def test_parametrize_1(dic):
    print(f'測試資料為{dic}')

執行結果如下

image-20210701233202805

增加可讀性

使用ids引數

引數化裝飾器有一個額外的引數ids,可以標識每一個測試用例,自定義測試資料結果的顯示,用來增加測試用例的可讀性

上程式碼

import pytest

data = [1, 2, 3]

ids = [f'TestData-{a}' for a in data]

@pytest.mark.parametrize('a', data ,ids= ids)
def test_parametrize(a):
    print(f'\n被載入測試資料為  {a}')

執行結果為

image-20210701234710810

自定義id做標識

除了使用ids引數增加輸出可讀性外,我們還可以在引數列表的引數旁邊定義一個id值來做標識

上程式碼

import pytest

data = [
pytest.param(1, id="this is test1"),
pytest.param(2, id="this is test2")
]



@pytest.mark.parametrize('a', data)
def test_parametrize(a):
    print(f'\n被載入測試資料為  {a}')

執行結果如下

image-20210701235116235

pytest.fixture()方式進行引數化

待更新

整理參考

linxu超

相關文章