一、前言

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

  比如登录操作,大部分用例都会先登录,那就需要把登录单独抽出来写一个函数,其他用例全部都调用这个登录函数就行。

  但是登录的账号不能写死,有时候我想用账号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"])

运行结果:

cec2014测试函数的python代码 python中test函数_数据

 

 

 

三、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"])

运行结果:

cec2014测试函数的python代码 python中test函数_数据_02

 

 

   添加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"])

运行结果:

cec2014测试函数的python代码 python中test函数_测试用例_03

 

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"])

运行结果:

cec2014测试函数的python代码 python中test函数_pytest_04

 

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

 

参考文章:https://www.jianshu.com/p/778eec13bb31