pytest(三)——参数化@pytest.mark.parametrize

目录

前言

参数化场景

实际Web UI自动化中的开发场景,比如是一个登录框

 parametrize单参数

“笛卡尔积”,多个参数化装饰器

重点知识

参考文献


前言

  •  @pytest.mark.parametrize 允许在测试函数或类中定义多组参数和fixtures
  •  pytest_generate_tests 允许定义自定义参数化方案或扩展(拓展)

参数化场景

        只有测试数据和期望结果不一样,但操作步骤是一样的测试用例可以用上参数化;可以看看下面的栗子

未参数化的代码

def test_1():
    assert 3 + 5 == 9


def test_2():
    assert 2 + 4 == 6


def test_3():
    assert 6 * 9 == 42

可以看到,三个用例都是加法然后断言某个值,重复写三个类似的用例有点冗余 

利用参数化优化之后的代码

@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
def test_eval(test_input, expected):
    print(f"测试数据{test_input},期望结果{expected}")
    assert eval(test_input) == expected

实际Web UI自动化中的开发场景,比如是一个登录框

  1. 你肯定需要测试账号空、密码空、账号密码都为空、账号不存在、密码错误、账号密码正确等情况
  2. 这些用例的区别就在于输入的测试数据和对应的交互结果
  3. 所以我们可以只写一条登录测试用例,然后把多组测试数据和期望结果参数化,节省很多代码量

 parametrize单参数

        参数化parametrize可以组装测试数据,在测试前定义好测试数据,并在测试用例中使用,提高测试效率。parametrize单参数单次循环的基本语法:

import pytest
@pytest.mark.parametrize("name", ["张三", "李四", "王五"])
def test_parametrize(name):
    print(f"我是:{name}")

 

parametrize读取json、excel、yaml

excelpath=r"D:\workplace20240513\pythonbase\python测试学习\01pytest学习\demo6-运行所有的案例信息\parametrizetest\test_data.xlsx"
def load_excel_data(file_path):
    df = pd.read_excel(file_path)
    return list(df.itertuples(index=False, name=None))

# 读取 YAML 文件
yamlpath=r"D:\workplace20240513\pythonbase\python测试学习\01pytest学习\demo6-运行所有的案例信息\parametrizetest\test_data.yaml"
def load_yaml_data(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        data = yaml.safe_load(file)
    return data['names']

# 读取 JSON 文件
jsonpath=r"D:\workplace20240513\pythonbase\python测试学习\01pytest学习\demo6-运行所有的案例信息\parametrizetest\test_data.json"
def load_json_data(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        data = json.load(file)
    return data['names'] 

'''
        在这里我试图从yaml文件中读取数据,然后实现参数的传递
    '''
    @pytest.mark.parametrize("name",load_yaml_data(yamlpath))
    def test_parametrize_yaml(self, name):
        print(f"我是:{name}")

    '''
           在这里我试图从json文件中读取数据,然后实现参数的传递
    '''
    @pytest.mark.parametrize("name", load_json_data(jsonpath))
    def test_parametrize_json(self, name):
        print(f"我是:{name}")

    # 从 Excel 文件中读取参数并传入多个参数
    @pytest.mark.parametrize("username,password,expected_status", load_excel_data(excelpath))
    def test_parametrize_excel(self,username, password, expected_status):
        print(f"用户名: {username}, 密码: {password}, 预期状态码: {expected_status}")

 yaml、json、excel格式


“笛卡尔积”,多个参数化装饰器

import pytest
# 笛卡尔积,组合数据
data_1 = [1, 2, 3]
data_2 = ['a', 'b']
@pytest.mark.parametrize('a', data_1)
@pytest.mark.parametrize('b', data_2)
def test_parametrize_1(a, b):
    print(f'笛卡尔积 测试数据为 : {a},{b}')

 

重点知识
  • 一个函数或一个类可以装饰多个 @pytest.mark.parametrize 
  • 这种方式,最终生成的用例数是n*m,比如上面的代码就是:参数a的数据有3个,参数b的数据有2个,所以最终的用例数有3*2=6条
  • 当参数化装饰器有很多个的时候,用例数都等于n*n*n*n*...

参考文献

Pytest进阶之fixture的使用(超详细)_pytest fixture用法-****博客

pytest之fixture用法01:fixture详解-百度开发者中心

Pytest系列(9) - 参数化@pytest.mark.parametrize - 小菠萝测试笔记 - 博客园

pytest进阶参数化用法01:parametrize详解_pytest parametrize-****博客

上一篇:【工具】arxiv_latex_cleaner 去除latex注释-1.修改编码


下一篇:小米 MIX FOLD工程固件 更换字库修复分区 资源预览与刷写说明-通过博文了解