问题背景
当我们写好一个函数进行自测的时候,通常需要多种数据场景进行验证,例如我写了一个乘法计算器函数:
import pytest
def func(a: int, b: int):
return a*b
def test01():
assert func(1, 2) == 2
assert func(2, 2) == 4
assert func(3, 2) == 6
assert func(4, 2) == 9
if __name__ == '__main__':
pytest.main(['参数化.py', '-s'])
执行结果:
collected 1 item
参数化.py F
================================== FAILURES ===================================
___________________________________ test01 ____________________________________
def test01():
assert func(1, 2) == 2
assert func(2, 2) == 4
assert func(3, 2) == 6
> assert func(4, 2) == 9
E assert 8 == 9
E + where 8 = func(4, 2)
参数化.py:22: AssertionError
=========================== short test summary info ===========================
FAILED 参数化.py::test01 - assert 8 == 9
============================== 1 failed in 0.22s ==============================
***Repl Closed***
通过在测试用例中输入不同的测试数据,进行场景编写,可实现所需要的目的。但是,这样的,测试用例维护性不强,耦合度高,可拓展性低,如果某天对func()
函数进行重构,则涉及到的用例全部需要维护。
@pytest.mark.parametrize进行参数化
pytest提供@pytest.mark.parametriza 可以实现参数化:
import pytest
def func(a: int, b: int):
return a*b
@pytest.mark.parametrize("intA,intB,expected",[(1,2,2),(2,2,4),(3,3,9),(4,4,15)])
def test01(intA,intB,expected):
print(f"{intA}*{intB}={expected}")
assert func(intA,intB) == expected
if __name__ == '__main__':
pytest.main(['参数化.py', '-s'])
执行结果:
collected 4 items
参数化.py
1*2=2
.2*2=4
.3*3=9
.4*4=15
F
================================== FAILURES ===================================
_______________________________ test01[4-4-15] ________________________________
intA = 4, intB = 4, expected = 15
@pytest.mark.parametrize("intA,intB,expected",[(1,2,2),(2,2,4),(3,3,9),(4,4,15)])
def test01(intA,intB,expected):
print(f"{intA}*{intB}={expected}")
> assert func(intA,intB) == expected
E assert 16 == 15
E + where 16 = func(4, 4)
参数化.py:20: AssertionError
=========================== short test summary info ===========================
FAILED 参数化.py::test01[4-4-15] - assert 16 == 15
========================= 1 failed, 3 passed in 0.22s =========================
***Repl Closed***
使用实例
import pytest
def loginDemo(loginName: str, password: str):
if loginName == "admin" and password == "123456":
return {"success": True, "loginInfo": "admin用户登录成功"}
elif loginName == "tester" and password == "123123":
return {"success": True, "loginInfo": "tester用户登录成功"}
else:
return {"success": False, "loginInfo": "该用户不允许登录或密码错误"}
data = [{"loginName": "admin", "password": "123456"}, {"loginName": "tester", "password": "123123"}, {"loginName": "hello", "password": "123456"}]
@pytest.mark.parametrize('dic', data)
def test01(dic):
assert loginDemo(dic['loginName'],dic['password'])['success'] == True
if __name__ == '__main__':
pytest.main(['参数化.py', '-s'])
执行结果:
collected 3 items
参数化.py ..F
================================== FAILURES ===================================
________________________________ test01[dic2] _________________________________
dic = {'loginName': 'hello', 'password': '123456'}
@pytest.mark.parametrize('dic', data)
def test01(dic):
> assert loginDemo(dic['loginName'],dic['password'])['success'] == True
E assert False == True
参数化.py:20: AssertionError
=========================== short test summary info ===========================
FAILED 参数化.py::test01[dic2] - assert False == True
========================= 1 failed, 2 passed in 0.21s =========================
***Repl Closed***