如何在同一场景中使用相同的步骤,但在pytestbdd中使用不同的参数?

2024-04-23 14:26:40 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个类似的场景:

    Scenario Outline: Example scenario
        Given the subprocess is running
        When I generate the input
        And I add <argument1> to the input
        And I add <argument2> to the input
        And this input is passed to the subprocess
        Then the output should match the <output> for <argument1> and <argument2>

我非常希望将'when'步骤重用为,例如And I add <argument> to the input,但不希望使用示例表,因为我希望通过在步骤定义/conftest文件中动态生成装置来实现。我目前正在使用@pytest.mark.parametrize对场景大纲进行参数化,如下所示:

import pytest
from pytest_bdd import scenario
from functools import partial
from some_lib import test_data, utils

@pytest.fixture(scope='module')
def context():
    return {}

scenario = partial(scenario, '../features/example.feature')

@pytest.mark.parametrize(
    [argument1, argument2],
    [(test_data.TEST_ARGUMENT[1], test_data.TEST_ARGUMENT[2]),],
)
@scenario('Example scenario')
def test_example_scenario(context, argument1, argument2):
    pass

我希望能够在同一场景中使用不同的参数重用相同的步骤定义,例如

@when('I add <argument> to the input')
def add_argument(context, argument):
    context['input'] = utils.add_argument(context['input'], argument)

而不是必须有两个步骤的定义,例如

@when('I add <argument1> to the input')
def add_argument(context, argument1):
    context['input'] = utils.add_argument(context['input'], argument1)

@when('I add <argument2> to the input')
def add_argument(context, argument2):
    context['input'] = utils.add_argument(context['input'], argument2)

pytest-bdd documentation似乎表明这是可能的,但我不能完全理解如果不使用示例表,如何实现这一点

Often it’s possible to reuse steps giving them a parameter(s). This allows to have single implementation and multiple use, so less code. Also opens the possibility to use same step twice in single scenario and with different arguments! [sic] (Emphasis my own)

有人对我如何做到这一点有什么想法吗

谢谢你一如既往地抽出时间


Tags: andthetoimportaddinputpytestdef
1条回答
网友
1楼 · 发布于 2024-04-23 14:26:40

我认为pytest-bdd文档更倾向于建议重新使用步骤,因为步骤定义中有一个变量,而不是硬编码的值……因此我认为文档没有为您的问题提供任何解决方案

无论如何,我使用的解决方案是动态获取step变量的值Pytest-bdd将为您在步骤中定义的每个变量创建一个pytest-fixture,因此只要您知道装置的名称,就可以通过调用request.getfixturevalue(name_of_fixture)来获取装置的值

对于您的情况,我将使用parsers.parse()作为步骤定义,以便变量argument1argument2将保存装置的名称而不是它们的值

示例

@when(parsers.parse('I add {argument1} to the input'))
def add_argument(request, context, argument1):
    # Remove angle brackets, because they are not part of the fixture name 
    argument1 = argument1.replace('<', '').replace('>', '')
    argument_value = request.getfixturevalue(argument1)
    context['input'] = utils.add_argument(context['input'], argument_value)

相关问题 更多 >