前言
我們在實際自動化測試中,某些測試用例是無法透過一組測試資料來達到驗證效果的,所以需要透過引數化來傳遞多組資料
在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
執行結果如下
裝飾測試函式
單個數據
當測試用例只需要一個引數時,我們使用列表存放測試資料,例如定義一個列表
data = [1,2]
使用@pytest。mark。parametrize裝飾器時,第一個引數使用變數a接收列表中的每個元素,第二個引數傳遞儲存資料的列表
在測試用例中使用同名的變數a接收測試資料,列表有多少個元素就會生成並執行多少個測試用例
上程式碼
import pytestdata = [1, 2 , 3]@pytest。mark。parametrize(‘a’, data)def test_parametrize(a): print(f‘\n被載入測試資料為{a}’)
執行結果如下
一組資料
當測試用例需要多個數據時,我們可以使用巢狀序列(巢狀元組&巢狀列表)的列表來存放測試資料
裝飾器@pytest。mark。parametrize()可以使用單個變數接收資料,也可以使用多個變數接收,同樣,測試用例函式也需要與其保持一致
當使用單個變數接收時,測試資料傳遞到測試函式內部時為列表中的每一個元素或者小列表,需要使用索引的方式取得每個資料
當使用多個變數接收資料時,那麼每個變數分別接收小列表或元組中的每個元素
列表巢狀多少個列表或元組,測生成多少條測試用例
上程式碼
import pytestdata = [ [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]
執行結果如下
組合資料
一個測試函式還可以同時被多個引數化裝飾器裝飾,多個裝飾器中的資料會進行交叉組合的方式傳遞給測試函式,進而生成n*n個測試用例,這也為我們的測試設計時提供了方便
上程式碼
import pytestdata_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}’)
執行結果如下
標記用例
當我們不想執行某組測試資料時,我們可以標記skip或skipif
當我們預期某組資料會執行失敗時,我們可以標記為xfail
上程式碼
import pytestdata1 = [ [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
執行結果如下
巢狀字典
資料列表中也可以使用字典型別的資料
上程式碼
import pytestdata_1 = ( { ‘user’: 1, ‘pwd’: 2 }, { ‘user’: 3, ‘pwd’: 4 })@pytest。mark。parametrize(‘dic’, data_1)def test_parametrize_1(dic): print(f‘測試資料為{dic}’)
執行結果如下
增加可讀性
使用ids引數
引數化裝飾器有一個額外的引數ids,可以標識每一個測試用例,自定義測試資料結果的顯示,用來增加測試用例的可讀性
上程式碼
import pytestdata = [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}’)
執行結果為
自定義id做標識
除了使用ids引數增加輸出可讀性外,我們還可以在引數列表的引數旁邊定義一個id值來做標識
上程式碼
import pytestdata = [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}’)
執行結果如下