前言
为了提高代码的复用性,我在写用例的时候,会用到函数,然后不用的用例去调用这个函数
比如登录操作,大部分的用例都会先登录,那就需要把登录单独用函数写出来,其他用例全部的调用这个登录函数就行
但是登录的账号不能写死,有时候我想用账号1去登录,执行用例1,用账号2登录执行用例2,所以需要对应的传参去完成登录
一、登录函数传参
把登录单独拿出来,写一个函数,传2个参数user和pwd,输入几组user,输入几组user,pwd参数化登录用例
测试用例传参需要用装饰器@pytest.mark,parmetrize里面写2个参数
- 第一个参数是字符串,多个参数中间用逗号隔开
- 第二个参数是list,多组数据用元祖类型
示例:这里去判断登录密码为空的情况抛出异常为例子
import pytest
test_login_data=[("admin","123"),("admin","")]
def login(user,pwd):
'''普通登录函数'''
print("登录账号:%s"%user)
print("登录密码:%s"%pwd)
if pwd:
return True
else:
return False
@pytest.mark.parametrize("user,pwd",test_login_data)
def test_login(user,pwd):
'''登录用例'''
result=login(user,pwd)
assert result==True,"失败原因:密码为空"
if __name__ == '__main__':
pytest.main(["-s","cnasuhua.py"])
运行结果:
============================= test session starts =============================
collected 2 items
cnasuhua.py 登录账号:admin
登录密码:123
.登录账号:admin
登录密码:
F
================================== FAILURES ===================================
_____________________________ test_login[admin-] ______________________________
user = 'admin', pwd = ''
@pytest.mark.parametrize("user,pwd",test_login_data)
def test_login(user,pwd):
'''登录用例'''
result=login(user,pwd)
> assert result==True,"失败原因:密码为空"
E AssertionError: 失败原因:密码为空
E assert False == True
cnasuhua.py:60: AssertionError
=========================== short test summary info ===========================
FAILED cnasuhua.py::test_login[admin-] - AssertionError: 失败原因:密码为空
========================= 1 failed, 1 passed in 0.08s =========================
Process finished with exit code 0
从上结果可以看出,一个运行成功,一个运行失败。但是互相不影响。
二、request参数
1)传1个参数
如果想把登录操作放到前置操作里,也就是用到@pytest.fixture装饰器,传参就用默认的request参数,
user=request.param这一步是接收传入的参数,这里就是传一个参数的情况
#encoding:utf-8
#@Time:2020/12/7 11:24
#@Author:sunny
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)
def test_login(login):
'''登录用例'''
a=login
print("测试用例中a的返回值:%s"%a)
assert a!=""
if __name__ == '__main__':
pytest.main(["-s","canshu.py"])
运行结果:
Testing started at 11:46 ...
============================= test session starts =============================collected 2 items
canshu.py 登录账户:admin2
.测试用例中a的返回值:admin2
登录账户:admin1
.测试用例中a的返回值:admin1
[100%]
============================== 2 passed in 0.03s ==============================
Process finished with exit code 0
添加indirect=True参数是为了把login当成一个函数去执行,而不是一个参数
2)传2个参数
如果用到@pytest.fixture,里面用2个参数情况,可以把多个参数用一个字典去存储,这样最终还只传一个参数
不同的参数再从字典里面取对应key值就行,如:user=request.param['user']
import pytest
test_user_data=[{
"user":"admin1","pwd":"123",
"user":"admin2","pwd":""
}]
@pytest.fixture(scope="module")
def login(request):
user=request.param["user"]
pwd=request.param["pwd"]
print("登录账户:%s"%user)
print("登录密码:%s"%pwd)
if pwd:
return True
else:
return False
@pytest.mark.parametrize("login",test_user_data,indirect=True)
def test_login(login):
'''登录用例'''
a=login
print("测试用例中loign的返回值:%s"%a)
# assert a,"失败原因:密码为空"
if __name__ == '__main__':
pytest.main(['-s','canshu.py'])
运行结果:
Testing started at 15:19 ...============================= test session starts =============================collected 1 item
canshu.py 登录账户:admin2
登录密码:
.测试用例中loign的返回值:False
[100%]
============================== 1 passed in 0.02s ==============================
Process finished with exit code 0
如果要用到login里面的返回值,def test_login(login)时,传入login参数,函数返回值就是login了
3)多个fixture(只加一个装饰器)
用例上面是可以同时放多个fixture的,也就是多个前置操作,可以支持装饰器叠加,使用parametrize装饰器
import pytest
data=[("admin1","pwd1"),("admin2","pwd2")]
@pytest.fixture(scope="module")
def input_user(request):
user=request.param
print("登录账号:%s" % user)
return user
@pytest.fixture(scope="module")
def input_pwd(request):
pwd=request.param
print("登录密码:%s" % pwd)
return pwd
@pytest.mark.parametrize("input_user,input_pwd",data, indirect=True)
def test_two_fixture(input_user,input_pwd):
print("fixture返回的内容:",input_user,input_pwd)
运行结果:
Testing started at 20:56 ...============================= test session starts =============================collected 2 items
canshu.py 登录账号:admin1
登录密码:pwd1
.fixture返回的内容: admin1 pwd1
登录账号:admin2
登录密码:pwd2
.fixture返回的内容: admin2 pwd2
[100%]
============================== 2 passed in 0.05s ==============================
Process finished with exit code 0
4)多个fixture(叠加装饰器)
用例上面是可以同时放多个fixture的,也就是多个前置操作,可以支持装饰器叠加,使用parametrize装饰器叠加时,用例组合是参数个数相乘,这里例子是2*2
import pytest
# data=[("admin1","pwd1"),("admin2","pwd2")]
user=["admin1","admin2"]
pwd=["pwd1","pwd2"]
@pytest.fixture(scope="module")
def input_user(request):
user=request.param
print("登录账号:%s" % user)
return user
@pytest.fixture(scope="module")
def input_pwd(request):
pwd=request.param
print("登录密码:%s" % pwd)
return pwd
@pytest.mark.parametrize("input_user",user, indirect=True)
@pytest.mark.parametrize("input_pwd",pwd, indirect=True)
def test_two_fixture(input_user,input_pwd):
print("fixture返回的内容:",input_user,input_pwd)
运行结果:
Testing started at 21:02 ...
============================= test session starts =============================collected 4 items
canshu.py 登录账号:admin1
登录密码:pwd1
.fixture返回的内容: admin1 pwd1
登录账号:admin2
.fixture返回的内容: admin2 pwd1
登录密码:pwd2
.fixture返回的内容: admin2 pwd2
登录账号:admin1
.fixture返回的内容: admin1 pwd2
[100%]
============================== 4 passed in 0.07s ==============================
Process finished with exit code 0
同理,如果user有3个参数,pwd有3个参数,那么组合起来的参数个数是3*3=9个。
善于跌倒仍喜爱奔跑~