pytest-bdd: Reusable step functions regression: Specific step doesn't override generic one anymore

After #534, with this conftest.py:

import pytest_bdd as bdd
import pytest

@pytest.fixture
def value():
    return []

@bdd.when(bdd.parsers.parse("I have a {thing} thing"))
def generic(thing, value):
    value.append(thing)

this test_specific.py:

import pytest_bdd as bdd

@bdd.when("I have a specific thing")
def specific(value):
    value.append("42")

@bdd.then(bdd.parsers.parse("The value should be {thing}"))
def check(thing, value):
    assert value == [thing]


bdd.scenarios("specific.feature")

and this specific.feature:

Scenario: Overlapping steps 1
        When I have a specific thing
        Then the value should be 42

Scenario: Overlapping steps 2
        When I have a generic thing
        Then the value should be generic

I would expect that specific takes precedence over generic, i.e., the value for the first test is "42", not "generic". This used to be the case, but isn’t anymore after that commit:

    @bdd.then(bdd.parsers.parse("The value should be {thing}"))
    def check(thing, value):
>       assert value == [thing]
E       AssertionError: assert ['specific'] == ['42']
E         At index 0 diff: 'specific' != '42'
E         Use -v to get more diff

Note, however, it does work fine when generic is moved from the conftest.py file into test_specific.py:

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 15 (9 by maintainers)

Commits related to this issue

Most upvoted comments

To make my example more clear, in my generic conftest.py for a big project, I have the steps defined in hierarchy of packages, like this:


tests/
    conftest.py
    steps/
        user/
            given.py
            when.py
            then.py
        order/
            given.py
            when.py
            then.py
        browser/
            given.py
            when.py
            then.py
        .../
    integration/
        test_feature_a.py
        test_feature_b.py
        ...
    unit/
        ...

and my root level conftest.py looks like this:

# conftest.py
from .steps.users.given import *
from .steps.users.when import *
from .steps.users.then import *

from .steps.order.given import *
from .steps.order.when import *
from .steps.order.then import *

# Steps for interaction with the browser
from .steps.browser.given import *
from .steps.browser.when import *
from .steps.browser.then import *

This is to keep sanity and distinction between common steps for a specific part of the system. I wouldn’t want to define all my steps in the root conftest.py, it would be a mess of a file, and it would constantly cause merge conflicts.