pytest-bdd icon indicating copy to clipboard operation
pytest-bdd copied to clipboard

Reuse parametrized or outline steps without having to change step text

Open davidemoro opened this issue 9 years ago • 3 comments
trafficstars

It seems that pytest-bdd is not able to decorate a single fixture with two or more given decorations like that:

  • I am in the {page_id} page logged in with user {user_id}
  • I am in the <page_id> page logged in with user <user_id>
  • I am in the <page_id> page logged in with user {user_id}

For example if I use singleton tests works fine, but if I use also scenario outlines the first iteration is fine but the second one fails (instead of the page_id input i get "<page_id>").

If I duplicate the given step using different description all works fine but it is ugly. What do you suggest to do?

davidemoro avatar Oct 17 '16 10:10 davidemoro

I'm having the same problem right now. It would be good to brainstorm how to solve this.

justuswilhelm avatar Sep 18 '17 07:09 justuswilhelm

This is something I've just run into also!

We have scenario outlines with:

     Then I get the price $<price>

And then in other scenarios (not outlines) we have:

   Then I get the price $40

Why can't I have a single step definition that implements this like:

    @then(parsers.parse('I get the price ${price}'))
    def check_customer_price(price, customer):
        assert float(price) == customer['calculated_price']

This breaks because the scenario outline supplies "<price>" for the price :-(

I think an improvement would be to have the value substituted before looking up the step. I believe that's how behave does it...

richard-reece avatar Nov 15 '17 23:11 richard-reece

Bump as I've also come across this, I've implemented a "hack" for the time being where I do:

def parameterized_or_literal(request, argument):
    if argument[0] == "<" and argument[-1] == ">":
        return request.getfixturevalue(argument[1:-1])
    return argument


@when(
    parsers.cfparse("... {foo}"),
    target_fixture="bar",
)
def step_def(request, foo):
    foo = parameterized_or_literal(request, foo)

    return ...

Obviously this is less than ideal as I have no argument type validation

WilliamWCYoung avatar Sep 07 '21 16:09 WilliamWCYoung