pytest-dev / pytest-bdd

BDD library for the pytest runner
https://pytest-bdd.readthedocs.io/en/latest/
MIT License
1.32k stars 221 forks source link

would you like reduce similar steps impl? #512

Closed bulletRush closed 2 years ago

bulletRush commented 2 years ago

for this situation:

Given a phone
Given a <black> color phone
Given a <size>GB phone
Given a large dark phone

currently, we need write four step implements. in my ext version, we can write step impl like:

@given("a phone")  # -> a white 1024GB phone
@given("a <color> color phone")  # -> a <color> 1024GB phone
@given("a <size>GB phone")  # -> a white <size> phone
@given("a large dark phone",  color="black", size=2048) # -> a black 2048GB phone
@given("a <color> color, <size>GB phone")  # -> a <color> <size> phone
def step_given_a_phone(color="white", size=1024):
    ...

if this feature is acceptable, i can make a PR to the latest version.

see commits:

ktzoulas commented 2 years ago

You can use fixtures for default parameters as a workaround. I have done this in the past for table parameters.

bulletRush commented 2 years ago

@ktzoulas You don't understand what I mean. for a better e.g.

@then("the goods should sold out", available=True)
@then("the goods should not sold out", available=False)
def step_check_sold_out(ava, available=True):
        assert ava == available

in current pytest-bdd version, you need write two step defs: step_check_sold_out and step_check_not_sold_out. but in my version, only need on step def.

elchupanebrej commented 2 years ago

@bulletRush could you please check https://github.com/elchupanebrej/pytest-bdd-ng and give your feedback if it covers your needs?

youtux commented 2 years ago

You can use a parser to achieve that result:

from pytest_bdd import then, parsers

@then(
    parsers.re("the goods should (?P<negation>not )sold out"),
    converters={"negation": bool},
)
def step_check_sold_out(ava, negation):
    assert ava == not negation
youtux commented 2 years ago

You can also extend the pytest_bdd.parsers.StepParser base class, and add this logic in the parse_arguments(...) method. That's what this abstract base class is for.