pytest(十三)--函数传参和fixture传参数request

前言

为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数。

比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登录函数就行。但是登录的账号不能写死,有时候我想用账号1去登录,执行用例1,用账号2去登录执行用例2,所以需要对函数传参。

登录函数传参

把登录单独出来,写一个函数,传2个参数user和pwd,写用例的时候调用登录函数,输入几组user,pwd参数化登录用例测试用例传参需要用装饰器@pytest.mark.parametrize,里面写两个参数。

  第一个参数是字符串,多个参数中间用逗号隔开

  第二个参数是list,多组数据用元组类型

#test_fix1.py
#coding:utf-8
import pytest
test_user_data=[("admin","123456"),("test","")]
def login(user,pwd):
    print("登录账号:{}".format(user))
    print("登录密码:%s"%pwd)
    if pwd:
        return True
    else:
        return False
@pytest.mark.parametrize("user,pwd",test_user_data)
def test_login(user,pwd):
    result=login(user,pwd)
    assert result==True,"失败原因:密码为空"
if __name__=="__main__":
    pytest.main(["-s","test_fix1.py"]) 

运行结果

 从结果可以看出,有2个用例,一个测试通过,一个测试失败了,互不影响。

request参数

如果想把登录操作放到前置操作里,也可以用到@pytest.fixture装饰器,传参就用默认的request参数user=request.param这一步是接收传入的参数,如下传入一个参数情况。

添加indirect=True参数是为了把login当成一个函数去执行,而不是一个参数。

indirect=True是指用test_users数据对"login"这个fixture进行参数化,虽然装饰器写在测试用例上,但是却是对测试用例使用的fixture进行传递数据,这正是indirect单词的意思。

#test_fix1.py
#coding:utf-8
import pytest
test_users=["admin","test",""]
@pytest.fixture(scope="module")
def login(request):
    user=request.param
    print("登录账户:%s"%user)
    return user
@pytest.mark.parametrize("login",test_users,indirect=True)
def test_login(login):
    a=login
    print("测试用例中login的返回值{}".format(a))
    assert a !="","账户为空"
if __name__=="__main__":
    pytest.main(["-s","test_fix1.py"])  

运行结果

 

 request传2个参数

如果用到@pytest.fixture,里面用2个参数情况,可以把多个参数用一个字典去存储,这样最终还是只传一个参数。

不同的参数再从字典里面取对应key值就行,如:user=request.param["user"]

 

#test_fix1.py
#coding:utf-8
import pytest
test_users=[{"user":"admin","pwd":"123456"},{"user":"test","pwd":""}]
@pytest.fixture(scope="module")
def login(request):
    user=request.param["user"]
    pwd=request.param["pwd"]
    print("登录账户:%s" % user)
    print("登录密码:{}".format(pwd))
    return pwd
@pytest.mark.parametrize("login",test_users,indirect=True)
def test_login(login):
    a=login
    print("测试用例中login的返回值{}".format(a))
    assert a !="","密码为空"
if __name__=="__main__":
    pytest.main(["-s","test_fix1.py"]) 

 运行结果

 

 如果要用到login里面的返回值,def test_login(login)时,传入login参数,函数返回值就是login了。

多个fixtrue

用例上面是可以同时放多个fixture的,也就是多个前置操作,可以支持装饰器叠加,使用parametrize装饰器叠加时,用例组合是2个参数个数相乘。

#test_fix1.py
#coding:utf-8
import pytest
test_users=["admin","test"]
test_pwd=["123456","888888"]
@pytest.fixture(scope="module")
def in_user(request):
    user=request.param
    print("登录账号:{}".format(user))
    return user

@pytest.fixture(scope="module")
def in_pwd(request):
    pwd=request.param
    print("登录密码:{}".format(pwd))
    return pwd

@pytest.mark.parametrize("in_user",test_users,indirect=True)
@pytest.mark.parametrize("in_pwd",test_pwd,indirect=True)
def test_login(in_user,in_pwd):
    a=in_user
    b=in_pwd
    print("账号,密码:{},{}".format(a,b))
    assert b
if __name__=="__main__":
    pytest.main(["-s","test_fix1.py"])

 运行结果:

 

 如果参数users有2个数据,参数pwd有2个数据,那么组合起来的案例是两个相乘,也就是2*2=4个用例

 

 

posted on 2020-07-30 14:05  星空6  阅读(696)  评论(0编辑  收藏  举报

导航