如何参数化夹具和测试功能

pytest可以在多个级别上实现测试参数化:

@pytest.mark.参数化:参数化测试功能

内置pytest.mark.参数化装饰器启用测试函数参数化。下面是一个典型的例子一个测试函数,该函数实现了对特定输入引线的检查至预期输出:

#test_expectation.py的内容
进口 pytest测试


@pytest测试.作记号.参数化(“测试输入,应为”, [("3+5", 8), ("2+4", 6), ("6*9", 42)])
定义 测试值(_E)(测试输入, 预期):
    断言 评估(测试输入) == 预期

这里@参数化decorator定义了三种不同的(测试输入,应为)元组,以便测试值(_E)函数将使用运行三次他们依次:

$pytest(美元)=================================平台linux——Python 3.x.y、pytest-8.x.y、plugy-1.x.yrootdir:/home/sweet/project收集了3个项目测试_期望.py..如果                                              [100%]====~=======:====2===>===+====1===>失败=================================____________________________测试值[6*9-42]_____________________________test_input=“6*9”,预期值=42@pytest.mark.parametrize(“测试输入,预期”,[(“3+5”,8),(“2+4”,6),((“6*9”,42)])def test_eval(测试输入,应为):>断言eval(test_input)==应为E断言错误:断言54==42
E+其中54=eval('6*9')

测试_期望.py:6:断言错误===============================
失败test_expectation.py::测试值[6*9-42]-断言错误:断言54。。。=======================1个失败,2个通过0.12s内========================

注释

参数值作为-is传递给测试(没有任何副本)。

例如,如果您将列表或dict作为参数值传递,并且测试用例代码对其进行了修改,这些修改将反映在随后的测试中测试用例调用。

注释

pytest默认情况下会转义unicode字符串中使用的任何非ascii字符因为它有几个缺点。然而,如果您想在参数化中使用unicode字符串并在终端中按原样查看它们(非转义),请使用此选项在您的pytest.ini文件:

[测试]
禁用测试退出和取消所有权限 = 真的

但请记住,这可能会导致不必要的副作用和甚至根据所使用的操作系统和当前安装的插件,所以使用它的风险自负。

按照本例的设计,只有一对输入/输出值发生故障简单的测试功能。和通常的测试函数参数一样,你可以看到输入输出回溯中的值。

注意,您还可以在类或模块上使用参数化标记(请参见如何使用属性标记测试函数)它将使用参数集调用多个函数,例如:

进口 pytest测试


@pytest测试.作记号.参数化(“n,应为”, [(1, 2), (, 4)])
 测试类:
    定义 测试简单案例(自己, n个, 预期):
        断言 n个 + 1 == 预期

    定义 测试怪人简单案例(自己, n个, 预期):
        断言 (n个 * 1) + 1 == 预期

要参数化模块中的所有测试,可以将pytestmark(测试标记)全局变量:

进口 pytest测试

pytestmark(测试标记) = pytest测试.作记号.参数化(“n,应为”, [(1, 2), (, 4)])


 测试类:
    定义 测试简单案例(自己, n个, 预期):
        断言 n个 + 1 == 预期

    定义 测试怪人简单案例(自己, n个, 预期):
        断言 (n个 * 1) + 1 == 预期

也可以在参数化中标记单个测试实例,例如,内置mark.xfail(标记.xfail):

#test_expectation.py的内容
进口 pytest测试


@pytest测试.作记号.参数化(
    “test_input,应为”,
    [("3+5", 8), ("2+4", 6), pytest测试.参数("6*9", 42, 标志=pytest测试.作记号.x失败)],
)
定义 测试值(_E)(测试输入, 预期):
    断言 评估(测试输入) == 预期

让我们运行一下:

$pytest(美元)=============================测试会话开始============================平台linux——Python 3.x.y、pytest-8.x.y、plugy-1.x.yrootdir:/home/sweet/project收集了3个项目测试_期望.py..x个                                              [100%]

=======================2个通过,1 x失败0.12s内=======================

之前导致故障的一个参数集显示为“xfailed”(预期失败)测试。

如果提供给参数化导致空列表-对于例如,如果它们是由某个函数动态生成的pytest由空参数设置标记选项。

要获取多个参数化参数的所有组合,可以堆叠参数化装饰师:

进口 pytest测试


@比重计.作记号.参数化(“x”, [0, 1])
@pytest测试.作记号.参数化(“y”, [2, ])
定义 测试_foo(x个, ):
    通过

这将运行参数设置为的测试x=0/y=2,x=1/y=2,x=0/y=3、和x=1/y=3按照装饰器的顺序排出参数。

基本pytest生成测试例子

有时您可能想实现自己的参数化方案或者实现一些动态来确定参数或范围固定装置。为此,您可以使用pytest生成测试在收集测试函数时调用。通过传入元函数对象,您可以检查请求的测试上下文,大多数重要的是,你可以打电话给metafunc.parametrize()导致参数化。

例如,假设我们想运行一个测试,获取字符串输入我们想通过一个新的pytest测试命令行选项。让我们先写接受字符串输入fixture函数参数:

#test_strings.py的内容


定义 测试有效字符串(字符串输入):
    断言 字符串输入.是否字母()

现在我们添加一个conftest.py公司包含添加命令行选项和测试函数的参数化:

#conftest.py的内容


定义 pytest_add选项(解析器):
    解析器.添加选项(
        “--字符串输入”,
        行动=“附加”,
        违约=[],
        帮助=“要传递给测试函数的字符串输入列表”,
    )


定义 pytest生成测试(元函数):
    如果 “字符串输入” 在里面 元函数.设备名称:
        元函数.参数化(“字符串输入”, 元函数.配置.获取选项(“字符串输入”))

如果我们现在传递两个字符串输入值,我们的测试将运行两次:

$pytest-q--stringnput=“hello”--stringiput=“world”test_strings.py..                                                                   [100%]
2个通过0.12s内

让我们也使用会导致测试失败的字符串:

$pytest-q--stringinput=“!”test_strings.py如果                                                                    [100%]====~=======:====2===>===+====1===>失败=================================___________________________测试有效字符串[!]___________________________stringinput=“!”定义test_valid_string(字符串输入):>断言字符串输入.isalpha()E断言错误:断言False
E+其中False=<内置方法是0xdeadbeef0001处str对象的alpha>()
E+其中<内置方法是位于0xdeadbeef0001的str对象的lpha>=“!”。是否字母

测试字符串.py:4:断言错误=========================简短的测试摘要信息==========================
失败test_strings.py::测试有效字符串[!]-断言错误:断言为False1个失败0.12s内

正如预期的那样,我们的测试功能失败了。

如果不指定字符串输入,将跳过它,因为metafunc.parametrize()将使用空参数调用列表:

$pytest-q-rs测试字符串.py                                                                    [100%]
===============================
跳过[1] test_strings.py:获取了空参数集['stringinput'],函数test_valid_string位于/home/sweet/project/test_strings.py:2跳过1个0.12s内

请注意,打电话时元函数.参数化多次使用不同的参数集这些集合不能重复,否则将引发错误。

更多示例

有关更多示例,您可能需要查看更多参数化示例.