pytest-dev / pytest

The pytest framework makes it easy to write small tests, yet scales to support complex functional testing
https://pytest.org
MIT License
12.14k stars 2.69k forks source link

A fixture with autouse set to False will always be used if it overrides a fixture with autouse set to True #3225

Open bngo92 opened 6 years ago

bngo92 commented 6 years ago

def test_bar(foo): pass

def test_baz(): pass

Returns the following error:

____ ERROR at setup of testbar ____

@pytest.fixture()
def foo():
  assert False

E assert False

____ ERROR at setup of testbaz ____

@pytest.fixture()
def foo():
  assert False

E assert False


I expect only test_bar to fail. Setting autouse to False for foo in conftest.py correctly causes only test_bar to fail.
ceridwen commented 6 years ago

I've encountered what may be another manifestation of this bug, only with parametrization. I'm doing some dynamic fixture creation based on command-line options. An autouse=True session fixture takes this fixture as an argument:

def pytest_configure(config):
    class DynamicFixturePlugin2(object):
        @pytest.fixture(scope='session', params=['foo, 'bar'] if config.getoption('--foo') else [''])
        def baz(self, request):
            return request.param
    config.pluginmanager.register(DynamicFixturePlugin2(), 'baz-fixture')

I realized that I accidentally created a test that uses that same name as a parameter.

@pytest.mark.parametrize('baz, ['foo', 'bar'])
def test(baz, ...):
   ....

This test just so happened to be the first test in the file it was in. If I then invoke pytest with this file as the first item in a list of test files and that test is the first test in that file, then I get the following error:

ScopeMismatch: You tried to access the 'function' scoped fixture 'baz' with a 'session' scoped request object, involved factories
conftest.py:141:  def autouse_fixture_that_depends_on_dynamic_fixture(request, baz, ...)

If it's not related, tell me and I'll file a separate bug.