前言

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

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

但是登录的账号不能写死,有时候我想用账号1去登录,执行用例1,用账号2登录执行用例2,所以需要对应的传参去完成登录

一、登录函数传参

把登录单独拿出来,写一个函数,传2个参数user和pwd,输入几组user,输入几组user,pwd参数化登录用例

测试用例传参需要用装饰器@pytest.mark,parmetrize里面写2个参数

  1. 第一个参数是字符串,多个参数中间用逗号隔开
  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个。

 

善于跌倒仍喜爱奔跑~