pytest学习14--函数传参和fixture传参request

前言:

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

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

1、登录函数传参

把登录单独成立,写一个函数,传2个参数user和psw,写用例的时候调用登录函数,输入几组user,psw参数化登录。

测试用例传参需要使用装饰器pytest.mark.parameterize(),里面写两个参数

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

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

例子:

# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File       : test_login.py
# Time       :2021/11/22 20:36
# Author     :author Kong_hua_sheng_25304
# version    :python 3.8
# Description:
"""
import pytest
test_login_data = [('admin','1111'),('admin','')]

def login(user,psw):
    """
    普通的登录函数
    :type psw: String
    :type user: String
    :param user:
    :param psw:
    :return:
    """
    print("\n登录账号:%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,"失败原因,密码为空"
    pass


if __name__ == '__main__':
    pytest.main(['-s','-q','test_login.py'])

  运行结果:

 

 

 

 

 

 

2、request参数

如果想把登录操作放在前置的操作里,也就是使用到@pytest.fixture()装饰器,传参就用默认的request参数,user = request.param这一步是接受传入的参数,本案例是传入一个参数的情况。

# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File       : test_login_request.py
# Time       :2021/11/22 20:51
# Author     :author Kong_hua_sheng_25304
# version    :python 3.8
# Description: request传参
"""
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):
    """
    登录用例
    :param login:
    :return:
    """
    a = login
    print("测试用例中login的返回值:%s"%a)
    assert a != ""


if __name__ == '__main__':
    pytest.main(['-s','-q','test_login_request.py'])

  执行结果:

 

 这里对indirect做一个解释:

添加indirect=True参数是为了把pytest.mark.para,eterize('login',test_user_data,indirect=True)中的login当成一个函数去执行,而不是一个参数。

1:     @pytest.mark.parameterize('login',test_user_data)

2:     @pytest.mark.parameterize('login',test_user_data,indirect=True)

当使用第一个装饰器的时候,login就是一个变量,执行后的结果就是 login = ['admin1','admin2']

当使用第二个装饰器的时候,login就变为一个可执行函数,再将params当参数传入login函数中去执行,当其他变量被赋值为login的时候。

上个代码例子中:

a = login 就是讲login函数的执行结果返回给a

总结:

  当indirect为True的时候,参数为固件函数名称的,执行的时候会当做函数来执行。

  当indirect为False的时候,参数为固件函数名称的,执行的时候会当做一个参数来执行。

3、request传递2个参数的时候

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

不同的参数再从字典里取对应的key'值就行。

# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File       : test_request_login2.py
# Time       :2021/11/22 21:18
# Author     :author Kong_hua_sheng_25304
# version    :python 3.8
# Description:使用request传递2个参数的情况
"""
import pytest

test_user_data = [{'user':'admin1','psw':"1111"},
                  {'user':'admin2','psw':""}]

@pytest.fixture(scope='module')
def login(request):
    """
    普通的登录函数,写在fixture中,在执行module之前执行次函数
    :param request:
    :return:
    """
    user = request.param['user']
    psw = request.param['psw']
    print('登录的账户为:%s 登录的密码为:%s'%(user,psw))
    if psw:
        return True
    else:
        return False

# indirect = True 的含义为 声明login为可执行的函数,而不是一个参数
@pytest.mark.parametrize('login',test_user_data,indirect=True)
def test_login(login):
    """
    测试函数 使用request传递2个参数
    :param login:
    :return:
    """
    a = login
    print("测试用例中login的返回值:%s "%a)
    assert a !="" , "失败原因 密码为空"


if __name__ == '__main__':
    pytest.main(['-s','-q','test_request_login2.py'])

  运行结果:

 4、多个fixture

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

# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File       : test_request_login3.py
# Time       :2021/11/22 21:33
# Author     :author Kong_hua_sheng_25304
# version    :python 3.8
# Description:使用parameterize装饰器叠加,参数的两个装饰器的参数组合
"""
import pytest

test_user = ['admin1','admin2']
test_psw = ['1111','2222']


@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):
    user = input_user
    psw = input_psw

    print("user = %s   psw = %s"%(user,psw))
    assert psw


if __name__ == '__main__':
    pytest.main(['-s','-q','test_request_login3.py'])

  运行结果:2*2=4共4种组合

 

posted @ 2021-11-22 21:31  GalaxyStar  阅读(530)  评论(0编辑  收藏  举报