我如何在相同的场景中使用相同的步骤,但在 pytest-bdd 中使用不同的参数?

问题描述

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

    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>

我非常想重用“何时”步骤,例如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 似乎表明这是可能的,但我无法完全理解如何在不使用示例表的情况下完成此任务。

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

有人对我如何实现这一目标有任何想法吗?

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

解决方法

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

无论如何,我使用了一个解决方案,它是动态获取步骤变量的值。 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)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...