2

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

    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 文档似乎表明这是可能的,但我无法完全理解如何在不使用示例表的情况下完成此操作。

通常可以重用为它们提供参数的步骤。这允许单一实现和多次使用,因此代码更少。还打开了在单个场景中两次使用相同步骤并使用不同参数的可能性![原文如此] (强调我自己的)

有没有人对我如何做到这一点有任何想法?

一如既往地感谢您的时间!

4

1 回答 1

1

我认为pytest-bdd由于步骤定义中的变量而不是硬编码值,该文档建议重用步骤...所以我认为该文档没有为您的问题提供任何解决方案。

无论如何,我使用了一个解决方案,即动态获取 step 变量的值。将为您在步骤中定义的每个变量Pytest-bdd创建一个,因此只要您知道夹具的名称,您就可以通过调用获取夹具的值。pytest-fixturerequest.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)
于 2021-07-26T14:13:34.187 回答