一、前言
为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数。
比如登录操作,大部分用例都会先登录,那就需要把登录单独抽出来写一个函数,其他用例全部都调用这个登录函数就行。
但是登录的账号不能写死,有时候我想用账号1去登录,执行用例1,用账号2去登录执行用例2,所以需要对函数传参。
二、登录函数传参
把登录单独成立,写一个函数,传2个参数user和psw,写用例的时候调用登录函数,输入几组user,psw参数化登录用例。
测试用例传参需要用装饰器@pytest.mark.parametrize,里面写两个参数。
第一个参数是字符串,多个参数中间用逗号隔开;
第二个参数是list,多组数据用元组类型。
import pytest # 测试登录数据 test_login_data = [("admin","111111"),("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) def test_login(user,psw): """登录用例""" result = login(user,psw) assert result == True,"失败原因:密码为空" if __name__ == "__main__": pytest.main(["-s","test_login.py"])
运行结果:
三、request参数
如果想把登录插座放在前置操作里,也就是用到@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) def test_login(login): """登录用例""" a = login print("测试用例中login的返回值:%s"%a) assert a != "" if __name__ == "__main__": pytest.main(["-s","test_login2.py"])
运行结果:
添加indirect = True参数是为了把login当成一个函数去执行,而不是一个参数。
四、request传两个参数
如果用到@pytest.fixture,里面用2个参数情况,可以把多个参数用一个字段去存储,这样最终还只传一个参数。
不同的参数再从字典里面取对应key值就行,如:user = request.param["user"]
import pytest # 测试账号数据 test_user_data = [{"user":"admin1","psw":"1111111"}, {"user":"admin2","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 # indirect = True 声明login是个函数 @pytest.mark.parametrize("login",test_user_data,indirect=True) def test_login(login): """登录用例""" a = login print("测试用例中login的返回值:%s"%a) assert a,"失败原因:密码为空" if __name__=="__main__": pytest.main(["-s","test_login3.py"])
运行结果:
E AssertionError: 失败原因:密码为空
E assert False
如果要用到login里面的返回值,def test_login(login)时,传入login参数,函数返回值就是login了。
五、多个fixture
用例上面是可以同时放多个fixture的,也就是多个前置操作,可以支持修饰器叠加,使用parametrize装饰器叠加时,用例组合是2个参数个数相乘。
import pytest # 测试账号数据 test_user = ["admin1","admin2"] test_psw = ["111111","222222"] @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) @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 b if __name__=="__main__": pytest.main(["-s","test_login4.py"])
运行结果:
如果参数user有2个数据,参数psw有2个数据,那么组合起来的案例是两个相乘,也就是组合2*2=4个用例。