Pytest参数化:parametrize简单应用

参数意思:

argnames:是一个字符串,是参数的名字,如果有多个参数时,用逗号分隔
argvalues:是一个列表(或者元祖),是具体的要传入的数据

indirect:为true时,那argnames一定是一个fixture函数名称,argvalues值将传入对应的fixture内,相当于@pytest.fixture(params=)的用法,默认False

ids:标记子用例执行名称,与argvalues数量一致,未指定自动生成,默认None

scope:如果指定,则表示参数的范围。范围用于按参数实例对测试进行分组。它还将覆盖任何fixture函数定义的范围,允许使用测试上下文或配置设置动态范围

argnames是一个参数:假设要测试密码的长度必须大于8位且小于16位。设计了几个密码

import pytest


@pytest.mark.parametrize('passwd', ['123', '12345678', '1234567890123456', '12345678901234561'])
def test_passwd_length(passwd):
    assert len(passwd) >= 8
    assert len(passwd) <= 16

argnames是两个参数:如果要验证用户名和密码呢,两个参数如何实现呢

import pytest


@pytest.mark.parametrize('user,passwd', [
    ('lowen', '123'), ('lowen', '12345678'),
    ('lowen', '1234567890123456'),
    ('lowenlowen', '12345678901234561')
])

def test_passwd_length(user, passwd):
    assert len(passwd) >= 8
    assert len(passwd) <= 16
    assert user == 'lowen'

 ids用法:

import pytest


@pytest.mark.parametrize('user,passwd',
                         [pytest.param('lowen', '123', id='case_name_1'),
                          pytest.param('lowen', '12345678', id='case_name_2'),
                          pytest.param('ll', '1234567890123456', id='case_name_3'),
                          pytest.param('lowenlowen', '12345678901234561', id='case_name_4')])
def test_passwd_length(user, passwd):
    assert len(passwd) >= 8
    assert len(passwd) <= 16
    assert user == 'lowen'

执行结果为:

 

@pytest.mark.parametrize(argnames="number", argvalues=[1, 2, 3], ids=["id1", "id2", "id3"]) 
def test_is_positive(number):
    print("number", number)

 

 上面的都是写固定的,实际的工作中,很多时候的参数都是实时读取的。这些参数数据都是动态读取来的。如何给参数动态传递

import pytest


def getparame() -> list:
    return [('lowen', '123'), ('lowen', '12345678'), ('ll', '1234567890123456'),
            ('lowenzishuoceshikaifa', '12345678901234561')]


@pytest.mark.parametrize('user,passwd',getparame())
def test_passwd_length(user, passwd):
    assert len(passwd) >= 8
    assert len(passwd) <= 16
    assert user == 'lowen'

执行结果为:

 

indirect用法:

import pytest

test_user_data = ['Tom', 'Lowen']


# 方法名作为参数
@pytest.fixture(scope='module')
def login(request):
    # 通过 request.param 获取参数
    user = request.param
    print(f"登录用户: {user}")
    return user


# 为True时,argnames一定是一个fixture函数名称,argvalues值将传入对应的fixture内,相当于@pytest.fixture(params=)的用法,默认False
@pytest.mark.parametrize("login", test_user_data, indirect=True)
def test_login(login):
    a = login
    print(f"用例中 login 的返回值; {a}")
    assert a != None

 

scope用法:

①小于fixture函数的scope范围: 

import pytest


@pytest.fixture(scope="class")
def login_user(request):
    user = request.param
    print("传入的用户名为:{}".format(user))
    return user


@pytest.fixture(scope="class")
def login_pwd(request):
    pwd = request.param
    print("密码为:{}".format(pwd))
    return pwd


class TestCase:
    user_info = [
        ("张三", 123)
    ]
    ids = ["case{}".format(i) for i in range(len(user_info))]

    @pytest.mark.parametrize("login_user,login_pwd", user_info, ids=ids, indirect=True, scope="function")
    def test_increment(self, login_user, login_pwd):
        print("测试类的读到的内容是{}{}".format(login_user, login_pwd))

    @pytest.mark.parametrize("login_user,login_pwd", user_info, ids=ids, indirect=True, scope="function")
    def test_increment2(self, login_user, login_pwd):
        print("测试类的读到的内容是{}{}".format(login_user, login_pwd))

 

 ②大于fixture函数的scope范围:

import pytest


@pytest.fixture(scope="function")
def login_user(request):
    user = request.param
    print("传入的用户名为:{}".format(user))
    return user


@pytest.fixture(scope="function")
def login_pwd(request):
    pwd = request.param
    print("密码为:{}".format(pwd))
    return pwd


class TestCase:
    user_info = [
        ("张三", 123)
    ]
    ids = ["case{}".format(i) for i in range(len(user_info))]

    @pytest.mark.parametrize("login_user,login_pwd", user_info, ids=ids, indirect=True, scope="class")
    def test_increment(self, login_user, login_pwd):
        print("测试类的读到的内容是{}{}".format(login_user, login_pwd))

    @pytest.mark.parametrize("login_user,login_pwd", user_info, ids=ids, indirect=True, scope="class")
    def test_increment2(self, login_user, login_pwd):
        print("测试类的读到的内容是{}{}".format(login_user, login_pwd))

 

③多个SCOPE范围为先执行的:

import pytest


@pytest.fixture(scope="class")
def login_user(request):
    user = request.param
    print("传入的用户名为:{}".format(user))
    return user


@pytest.fixture(scope="class")
def login_pwd(request):
    pwd = request.param
    print("密码为:{}".format(pwd))
    return pwd


class TestCase:
    user_info = [
        ("张三", 123)
    ]
    ids = ["case{}".format(i) for i in range(len(user_info))]

    @pytest.mark.parametrize("login_user,login_pwd", user_info, ids=ids, indirect=True, scope="function")
    def test_increment(self, login_user, login_pwd):
        print("测试类的读到的内容是{}{}".format(login_user, login_pwd))

    @pytest.mark.parametrize("login_user,login_pwd", user_info, ids=ids, indirect=True, scope="class")
    def test_increment2(self, login_user, login_pwd):
        print("测试类的读到的内容是{}{}".format(login_user, login_pwd))

 

与③相比调整一下顺序:

import pytest


@pytest.fixture(scope="class")
def login_user(request):
    user = request.param
    print("传入的用户名为:{}".format(user))
    return user


@pytest.fixture(scope="class")
def login_pwd(request):
    pwd = request.param
    print("密码为:{}".format(pwd))
    return pwd


class TestCase:
    user_info = [
        ("张三", 123)
    ]
    ids = ["case{}".format(i) for i in range(len(user_info))]

    @pytest.mark.parametrize("login_user,login_pwd", user_info, ids=ids, indirect=True, scope="class")
    def test_increment(self, login_user, login_pwd):
        print("测试类的读到的内容是{}{}".format(login_user, login_pwd))

    @pytest.mark.parametrize("login_user,login_pwd", user_info, ids=ids, indirect=True, scope="function")
    def test_increment2(self, login_user, login_pwd):
        print("测试类的读到的内容是{}{}".format(login_user, login_pwd))

 

posted @ 2022-03-30 16:41  北京测试菜鸟  阅读(673)  评论(0)    收藏  举报