1. 程式人生 > 實用技巧 >pytest 引數化操作 @pytest.mark.parametrize (結合fixture使用)

pytest 引數化操作 @pytest.mark.parametrize (結合fixture使用)

@pytest.mark.parametrize 裝飾器可以實現用例引數化

@pytest.mark.parametrize("引數名",資料) #實現自定義引數名稱,並進行傳入引數資料


舉例:

import pytest
#自定義兩組資料
test_datas = [(1, 2, 3),
        (11, 22, 33)]

datas_dict = [
{"a": 1, "b": 2, "c": 3},
{"a": 11, "b": 22, "c": 33},
{"a": 111, "b": 222, "c": 333}]


# 直接寫入資料
@pytest.mark.parametrize("a, b, c", [(1, 2, 3), (4, 5, 9)]) #直接將引數寫到()裡面
def test_add_case1(a, b, c):
  res = a + b
  assert res == c

# 引數為列表中巢狀元組
@pytest.mark.parametrize("data", test_datas)  #自命名一個引數名data,將測試資料test_data 傳給 data
def test_add_case2(data):
    res = data[0] + data[1]
    assert res == data[2]

# 引數為列表中巢狀字典
@pytest.mark.parametrize("data", datas_dict)   #自命名一個引數名data,將測試資料datas_dict傳給data
def test_add_case3(data):
res = data["a"] + data["b"]
assert res == data["c"]

例項:

1、結合登入函式進行引數傳遞:
import pytest
#定義一組測試資料
test_login_data = [("admin", "123456"),
            ("admin", " ")]

def login(user, psw):
'''登入函式'''
  print("賬戶:%s" %user)
  print("密碼:%s" %psw)
  if psw:
    return True
  else:
    return False

@pytest.mark.parametrize("user, psw", test_login_data)    #這是login的測試函式,在用例上用上裝飾器,從而直接使用引數
def test_login(user, psw):
'''用例'''
  result = login(user, psw)
  assert result == True, "失敗原因:密碼為空"


if __name__ == "__main__":
  pytest.main(["-v", "test_demo.py"])

  

2、使用裝飾器@pytest.fixture寫登入函式

把登入放到前置條件裡,使用@pytest.fixture裝飾器:使用預設的request引數
如:user = request.param 用來接收傳入的引數

import pytest
# 定義一組測試資料
test_user_data = ["admin1", "admin2"]

@pytest.fixture(scope="module")
def login(request):
  user = request.param
  print("賬戶:%s"%user)
  return user

@pytest.mark.parametrize("login", test_user_data, indirect=True)     #indire=True標識login是個函式,只是在這被用作了引數
def test_login(login):
'''這是一條用例'''
  a = login
  print("用例中login的返回值:%s" % a)
  assert a != ""


if __name__ == "__main__":
  pytest.main(["-v", "test_demo.py"])

  

3、假設使用@pytest.fixture裝飾器,遇到登入賬號有多個引數時,可以用一個字典去儲存,
這樣的結果也是隻傳一個引數,但是隻需不同的引數從字典裡面取對應key值就行,如: user = request.param["user"]
import pytest

# 定義一組測試資料
test_user_data = [{"user": "admin1", "psw": "111111"},
            {"user": "admin1", "psw": ""}]

@pytest.fixture(scope="module")
def login(request):
  user = request.param["user"]
  psw = request.param["psw"]
  print("賬戶:%s" % user)
  print("密碼:%s" % psw)
  if psw:
    return True
  else:
    return False


@pytest.mark.parametrize("login", test_user_data, indirect=True)       # indirect=True 這個標識login是個函式,在這被用作了引數直接傳遞了
def test_login(login):
  '''用例'''
  a = login
  print("用例中login的返回值:%s" % a)
  assert a, "失敗原因:密碼為空"


if __name__ == "__main__":
  pytest.main(["-v", "test_demo.py"])

  

4、因為在用例上可以存在多個fixture來當做前置操作條件,
因此可以使用多個@pytest.mark.parametrize裝飾器但是用例執行次數也會被翻倍
import pytest

# 定義一組測試資料
test_user = ["admin1", "admin2"]
test_psw = ["11111", "22222"]


@pytest.fixture(scope="module")
def input_user(request):   #這是輸入賬戶名的
  user = request.param
  print("賬戶:%s" % user)
  return user


@pytest.fixture(scope="module")   
def input_psw(request):      #這是輸入密碼的
  psw = request.param
  print("密碼:%s" % psw)
  return psw

 

@pytest.mark.parametrize("input_user", test_user, indirect=True)     #使用2個裝飾器,來分別對user和psw來裝飾,用例執行後會看見一共執行了4次,各2次
@pytest.mark.parametrize("input_psw", test_psw, indirect=True)
def test_login(input_user, input_psw):
  '''用例'''
  a = input_user
  b = input_psw
  print("測試資料a:%s,b:%s"   %(a,b))
  assert a

if __name__ == "__main__":
  pytest.main(["-v", "test_demo.py"])