Skip to content

Pytest 参数化用例


简介

Pytest 中的参数化是一种非常有用的功能,通过参数的方式传递数据,从而实现数据和脚本分离。允许在同一个测试函数上多次运行相同的测试,使用不同的输入数据进而生成多个测试用例。


参数化的优点

  1. 简化测试代码:使用参数化测试,在测试代码中可以使用单个测试函数来覆盖多种不同的测试情况。这样可以避免编写大量重复的测试代码,并提高代码的可读性和维护性。

  2. 减少维护成本:如果需要对测试逻辑进行更改或添加更多测试用例,只需修改一个参数化测试案例,就可以覆盖所有相关的测试情况,减少了维护的工作量和成本。


使用方法

使用 @pytest.mark.parametrize() 装饰器为测试函数提供参数化数据。

@pytest.mark.parametrize(
    "变量名", 
    [变量值],
    ids=[用例名]
)
def test_demo(变量名):
    result = 变量名
    ...

支持参数类型

Pytest 的参数化功能允许灵活地为测试函数提供不同的输入参数:

  • 单参数
  • 多参数
  • 用例重命名
  • 笛卡尔积

传入单参数

单参数,可以将数据放在列表或者元组中。

search_list = ['appium','selenium','pytest']

@pytest.mark.parametrize('name',search_list)
def test_search(name):
    assert name in search_list

运行结果:


多参数情况

将数据放在列表嵌套元组或者列表中。

# 数据放在元组中
@pytest.mark.parametrize(
    "test_input,expected",
    [
        ("3+5",8),
        ("2+5",7),
        ("7+5",12)
    ]
)
def test_mark_more(test_input,expected):
    assert eval(test_input) == expected

# 数据放在列表中
@pytest.mark.parametrize(
    "test_input,expected",
    [
        ["3+5",8],
        ["2+5",7],
        ["7+5",12]
    ]
)
def test_mark_more(test_input,expected):
    assert eval(test_input) == expected

运行结果:


用例重命名 - 添加 ids 参数

通过 ids 参数,将别名放在列表中。注意,ids 列表参数的个数要与参数值的个数一致。

@pytest.mark.parametrize(
    "test_input,expected",
    [
        ("3+5",8),
        ("2+5",7),
        ("7+5",12)
    ],
    ids=['add_3+5=8', 'add_2+5=7','add_3+5=12']
)
def test_mark_more(test_input,expected):
    assert eval(test_input) == expected

注意:当别名为中文时,会显示为 unicode 编码,需要自定义插件解决。


笛卡尔积

  • 两组数据:

  • a=[1,2,3]

  • b=[a,b,c]

  • 对应有几种组合形势 ?

  • (1,a),(1,b),(1,c)

  • (2,a),(2,b),(2,c)
  • (3,a),(3,b),(3,c)

代码示例:

@pytest.mark.parametrize(
    "b",["a","b","c"]
)
@pytest.mark.parametrize(
    "a",[1,2,3]
)
def test_param1(a, b):
    print(f"笛卡积形式的参数化中 a={a} , b={b}")

运行结果:


总结

  • 参数化测试用例的优点。
  • 参数化测试用例的实现方案。