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个用例