Skip to content

Fixture not found in test, but found in list of fixtures #3039

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
EvgeniyMakhmudov opened this issue Dec 15, 2017 · 12 comments
Closed

Fixture not found in test, but found in list of fixtures #3039

EvgeniyMakhmudov opened this issue Dec 15, 2017 · 12 comments
Labels
topic: fixtures anything involving fixtures directly or indirectly type: question general question, might be closed after 2 weeks of inactivity

Comments

@EvgeniyMakhmudov
Copy link

I have a test project with this sctucture

(pytestbug) Evgenijs-MacBook-Pro:src makhmudovevgeniy$ tree
.
├── __init__.py
├── conftest.py
├── package_a
│   ├── __init__.py
│   ├── conftest.py
│   └── test_a.py
└── package_b
    ├── __init__.py
    ├── conftest.py
    └── test_b.py

My goal is use fixture from package_a for test in package_b. For this i used pytest_plugins

Content of conftest's files:

(pytestbug) Evgenijs-MacBook-Pro:src makhmudovevgeniy$ cat conftest.py
import pytest

@pytest.fixture
def fixture_top():
    return '-top_'

(pytestbug) Evgenijs-MacBook-Pro:src makhmudovevgeniy$ cat package_a/conftest.py
import pytest

@pytest.fixture
def fixture_a1(fixture_top):
    return fixture_top + '-a1_'

(pytestbug) Evgenijs-MacBook-Pro:src makhmudovevgeniy$ cat package_b/conftest.py
import pytest

pytest_plugins = [
    'src.package_a.conftest'
]

@pytest.fixture
def fixture_b1(fixture_top):
    return fixture_top + '-b1_'

Content of test (important test_b2):

(pytestbug) Evgenijs-MacBook-Pro:src makhmudovevgeniy$ cat package_b/test_b.py
def test_b1(fixture_b1):
    pass

def test_b2(fixture_b1, fixture_a1):
    pass

Test failed with message fixture not found:

(pytestbug) Evgenijs-MacBook-Pro:src makhmudovevgeniy$ pytest package_b
=========================================================================================== test session starts ============================================================================================
platform darwin -- Python 3.6.3, pytest-3.2.5, py-1.5.1, pluggy-0.4.0
rootdir: /Users/makhmudovevgeniy/Projects/pytestbug/src, inifile:
collected 2 items

package_b/test_b.py .E

================================================================================================== ERRORS ==================================================================================================
________________________________________________________________________________________ ERROR at setup of test_b2 _________________________________________________________________________________________
file /Users/makhmudovevgeniy/Projects/pytestbug/src/package_b/test_b.py, line 4
def test_b2(fixture_b1, fixture_a1):
E       fixture 'fixture_a1' not found
>       available fixtures: cache, capfd, capsys, doctest_namespace, fixture_b1, fixture_top, monkeypatch, pytestconfig, record_xml_property, recwarn, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

/Users/makhmudovevgeniy/Projects/pytestbug/src/package_b/test_b.py:4
==================================================================================== 1 passed, 1 error in 0.02 seconds =====================================================================================

But if look in debug output we see that fixture_a1 founded:

(pytestbug) Evgenijs-MacBook-Pro:src makhmudovevgeniy$ pytest package_b --trace-config --fixtures
PLUGIN registered: <_pytest.config.PytestPluginManager object at 0x10f86ee48>
PLUGIN registered: <_pytest.config.Config object at 0x11009a908>
PLUGIN registered: <module '_pytest.mark' from '/usr/local/lib/python3.6/site-packages/_pytest/mark.py'>
PLUGIN registered: <module '_pytest.main' from '/usr/local/lib/python3.6/site-packages/_pytest/main.py'>
PLUGIN registered: <module '_pytest.terminal' from '/usr/local/lib/python3.6/site-packages/_pytest/terminal.py'>
PLUGIN registered: <module '_pytest.runner' from '/usr/local/lib/python3.6/site-packages/_pytest/runner.py'>
PLUGIN registered: <module '_pytest.python' from '/usr/local/lib/python3.6/site-packages/_pytest/python.py'>
PLUGIN registered: <module '_pytest.fixtures' from '/usr/local/lib/python3.6/site-packages/_pytest/fixtures.py'>
PLUGIN registered: <module '_pytest.debugging' from '/usr/local/lib/python3.6/site-packages/_pytest/debugging.py'>
PLUGIN registered: <module '_pytest.unittest' from '/usr/local/lib/python3.6/site-packages/_pytest/unittest.py'>
PLUGIN registered: <module '_pytest.capture' from '/usr/local/lib/python3.6/site-packages/_pytest/capture.py'>
PLUGIN registered: <module '_pytest.skipping' from '/usr/local/lib/python3.6/site-packages/_pytest/skipping.py'>
PLUGIN registered: <module '_pytest.tmpdir' from '/usr/local/lib/python3.6/site-packages/_pytest/tmpdir.py'>
PLUGIN registered: <module '_pytest.monkeypatch' from '/usr/local/lib/python3.6/site-packages/_pytest/monkeypatch.py'>
PLUGIN registered: <module '_pytest.recwarn' from '/usr/local/lib/python3.6/site-packages/_pytest/recwarn.py'>
PLUGIN registered: <module '_pytest.pastebin' from '/usr/local/lib/python3.6/site-packages/_pytest/pastebin.py'>
PLUGIN registered: <module '_pytest.helpconfig' from '/usr/local/lib/python3.6/site-packages/_pytest/helpconfig.py'>
PLUGIN registered: <module '_pytest.nose' from '/usr/local/lib/python3.6/site-packages/_pytest/nose.py'>
PLUGIN registered: <module '_pytest.assertion' from '/usr/local/lib/python3.6/site-packages/_pytest/assertion/__init__.py'>
PLUGIN registered: <module '_pytest.junitxml' from '/usr/local/lib/python3.6/site-packages/_pytest/junitxml.py'>
PLUGIN registered: <module '_pytest.resultlog' from '/usr/local/lib/python3.6/site-packages/_pytest/resultlog.py'>
PLUGIN registered: <module '_pytest.doctest' from '/usr/local/lib/python3.6/site-packages/_pytest/doctest.py'>
PLUGIN registered: <module '_pytest.cacheprovider' from '/usr/local/lib/python3.6/site-packages/_pytest/cacheprovider.py'>
PLUGIN registered: <module '_pytest.freeze_support' from '/usr/local/lib/python3.6/site-packages/_pytest/freeze_support.py'>
PLUGIN registered: <module '_pytest.setuponly' from '/usr/local/lib/python3.6/site-packages/_pytest/setuponly.py'>
PLUGIN registered: <module '_pytest.setupplan' from '/usr/local/lib/python3.6/site-packages/_pytest/setupplan.py'>
PLUGIN registered: <module '_pytest.warnings' from '/usr/local/lib/python3.6/site-packages/_pytest/warnings.py'>
PLUGIN registered: <_pytest.capture.CaptureManager object at 0x11048f400>
PLUGIN registered: <module 'src.conftest' (<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x11048f588>)>
PLUGIN registered: <module 'src.package_b.conftest' (<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x11048f588>)>
PLUGIN registered: <module 'src.package_a.conftest' (<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x11048f588>)>
PLUGIN registered: <Session 'src'>
PLUGIN registered: <_pytest.cacheprovider.LFPlugin object at 0x11082cd68>
PLUGIN registered: <_pytest.terminal.TerminalReporter object at 0x11082cdd8>
PLUGIN registered: <_pytest.fixtures.FixtureManager object at 0x110855a58>
=========================================================================================== test session starts ============================================================================================
platform darwin -- Python 3.6.3, pytest-3.2.5, py-1.5.1, pluggy-0.4.0
using: pytest-3.2.5 pylib-1.5.1
active plugins:
    4555468360          : <_pytest.config.PytestPluginManager object at 0x10f86ee48>
    pytestconfig        : <_pytest.config.Config object at 0x11009a908>
    mark                : /usr/local/lib/python3.6/site-packages/_pytest/mark.py
    main                : /usr/local/lib/python3.6/site-packages/_pytest/main.py
    terminal            : /usr/local/lib/python3.6/site-packages/_pytest/terminal.py
    runner              : /usr/local/lib/python3.6/site-packages/_pytest/runner.py
    python              : /usr/local/lib/python3.6/site-packages/_pytest/python.py
    fixtures            : /usr/local/lib/python3.6/site-packages/_pytest/fixtures.py
    debugging           : /usr/local/lib/python3.6/site-packages/_pytest/debugging.py
    unittest            : /usr/local/lib/python3.6/site-packages/_pytest/unittest.py
    capture             : /usr/local/lib/python3.6/site-packages/_pytest/capture.py
    skipping            : /usr/local/lib/python3.6/site-packages/_pytest/skipping.py
    tmpdir              : /usr/local/lib/python3.6/site-packages/_pytest/tmpdir.py
    monkeypatch         : /usr/local/lib/python3.6/site-packages/_pytest/monkeypatch.py
    recwarn             : /usr/local/lib/python3.6/site-packages/_pytest/recwarn.py
    pastebin            : /usr/local/lib/python3.6/site-packages/_pytest/pastebin.py
    helpconfig          : /usr/local/lib/python3.6/site-packages/_pytest/helpconfig.py
    nose                : /usr/local/lib/python3.6/site-packages/_pytest/nose.py
    assertion           : /usr/local/lib/python3.6/site-packages/_pytest/assertion/__init__.py
    junitxml            : /usr/local/lib/python3.6/site-packages/_pytest/junitxml.py
    resultlog           : /usr/local/lib/python3.6/site-packages/_pytest/resultlog.py
    doctest             : /usr/local/lib/python3.6/site-packages/_pytest/doctest.py
    cacheprovider       : /usr/local/lib/python3.6/site-packages/_pytest/cacheprovider.py
    freeze_support      : /usr/local/lib/python3.6/site-packages/_pytest/freeze_support.py
    setuponly           : /usr/local/lib/python3.6/site-packages/_pytest/setuponly.py
    setupplan           : /usr/local/lib/python3.6/site-packages/_pytest/setupplan.py
    warnings            : /usr/local/lib/python3.6/site-packages/_pytest/warnings.py
    capturemanager      : <_pytest.capture.CaptureManager object at 0x11048f400>
    /Users/makhmudovevgeniy/Projects/pytestbug/src/conftest.py: /Users/makhmudovevgeniy/Projects/pytestbug/src/conftest.py
    /Users/makhmudovevgeniy/Projects/pytestbug/src/package_b/conftest.py: /Users/makhmudovevgeniy/Projects/pytestbug/src/package_b/conftest.py
    src.package_a.conftest: /Users/makhmudovevgeniy/Projects/pytestbug/src/package_a/conftest.py
    session             : <Session 'src'>
    lfplugin            : <_pytest.cacheprovider.LFPlugin object at 0x11082cd68>
    terminalreporter    : <_pytest.terminal.TerminalReporter object at 0x11082cdd8>
    funcmanage          : <_pytest.fixtures.FixtureManager object at 0x110855a58>
rootdir: /Users/makhmudovevgeniy/Projects/pytestbug/src, inifile:
collected 2 items
cache
    Return a cache object that can persist state between testing sessions.

    cache.get(key, default)
    cache.set(key, value)

    Keys must be a ``/`` separated value, where the first part is usually the
    name of your plugin or application to avoid clashes with other cache users.

    Values can be any object handled by the json stdlib module.
capsys
    Enable capturing of writes to sys.stdout/sys.stderr and make
    captured output available via ``capsys.readouterr()`` method calls
    which return a ``(out, err)`` tuple.
capfd
    Enable capturing of writes to file descriptors 1 and 2 and make
    captured output available via ``capfd.readouterr()`` method calls
    which return a ``(out, err)`` tuple.
doctest_namespace
    Inject names into the doctest namespace.
pytestconfig
    the pytest config object with access to command line opts.
record_xml_property
    Add extra xml properties to the tag for the calling test.
    The fixture is callable with ``(name, value)``, with value being automatically
    xml-encoded.
monkeypatch
    The returned ``monkeypatch`` fixture provides these
    helper methods to modify objects, dictionaries or os.environ::

        monkeypatch.setattr(obj, name, value, raising=True)
        monkeypatch.delattr(obj, name, raising=True)
        monkeypatch.setitem(mapping, name, value)
        monkeypatch.delitem(obj, name, raising=True)
        monkeypatch.setenv(name, value, prepend=False)
        monkeypatch.delenv(name, value, raising=True)
        monkeypatch.syspath_prepend(path)
        monkeypatch.chdir(path)

    All modifications will be undone after the requesting
    test function or fixture has finished. The ``raising``
    parameter determines if a KeyError or AttributeError
    will be raised if the set/deletion operation has no target.
recwarn
    Return a WarningsRecorder instance that provides these methods:

    * ``pop(category=None)``: return last warning matching the category.
    * ``clear()``: clear list of warnings

    See http://docs.python.org/library/warnings.html for information
    on warning categories.
tmpdir_factory
    Return a TempdirFactory instance for the test session.
tmpdir
    Return a temporary directory path object
    which is unique to each test function invocation,
    created as a sub directory of the base temporary
    directory.  The returned object is a `py.path.local`_
    path object.

------------------------------------------------------------------------------------ fixtures defined from src.conftest ------------------------------------------------------------------------------------
fixture_top
    conftest.py:4: no docstring available

------------------------------------------------------------------------------- fixtures defined from src.package_a.conftest -------------------------------------------------------------------------------
fixture_a1
    package_a/conftest.py:4: no docstring available

------------------------------------------------------------------------------- fixtures defined from src.package_b.conftest -------------------------------------------------------------------------------
fixture_b1
    package_b/conftest.py:12: no docstring available

Pip list:

(pytestbug) Evgenijs-MacBook-Pro:src makhmudovevgeniy$ pip list --format=columns
Package    Version
---------- -------
attrs      17.3.0
pip        9.0.1
pluggy     0.6.0
py         1.5.2
pytest     3.3.1
setuptools 38.2.4
six        1.11.0

What is going wrong? Fixture in list, why i can't use it? What i doing wrong? Is it bug or feature?

@EvgeniyMakhmudov
Copy link
Author

Khmm... anybody can produce some reaction on this ?

@nicoddemus
Copy link
Member

Hi @EvgeniyMakhmudov, sorry for the lack of response.

Currently you can't reference conftest.py files using pytest_plugins; I remember looking at the code and there was a special case for that, so it does not seem like a bug but intended, I'm not sure what the reason is though.

@RonnyPfannschmidt you know why is that feature in place?

@nicoddemus nicoddemus added topic: fixtures anything involving fixtures directly or indirectly type: question general question, might be closed after 2 weeks of inactivity labels Dec 22, 2017
@CJ-Wright
Copy link

I've also ran into this issue when using xonsh. What is the suggest workaround for this? Should I copy paste conftest.py into the files using plugins?

@RonnyPfannschmidt
Copy link
Member

bascially this works as intended - conftests are registred as plugins, but in actual execution they are ahadowed out

so fixtures from conftests that get disabled for a directory tree are not availiable

fixtures from plugin files would be availiable however

@rafalkasa
Copy link

rafalkasa commented Feb 17, 2019

  • conftest.py:

    import pytest
    
    pytest_plugins = [
       "package_a.conftest_a",
       "package_b.conftest_b"
    ]
    
    @pytest.fixture
    def fixture_top():
        return '-top_'
  • package_a/conftest_a.py:

    import pytest
    
    @pytest.fixture
    def fixture_a1(fixture_top):
        return fixture_top + '-a1_'
  • package_b/conftest_b.py

    import pytest
    
    @pytest.fixture
    def fixture_b1(fixture_top):
        return fixture_top + '-b1_'
  • package_b/test_b.py

    def test_b1(fixture_b1):
        pass
    
    def test_b2(fixture_b1, fixture_a1):
        pass

As a note that the respective directories referred to in "package_a.conftest" need to have __init__.py files for the plugins to be loaded by pytest

Please remember to not naming your subpackage fixtures file conftest.py this can create the exception error

    (plugin_name, plugin, self._name2plugin))
E   ValueError: Plugin already registered: some_test/package_a/conftest.py=<module 'package_a.conftest' from 'some_tes/package_a/conftest.py'>
E   {'1654192155784': <_pytest.config.PytestPluginManager object at 0x0000018125892C88>,
...

@ilyakamens
Copy link

A bit late to the party, but: I understand this works as intended, but if I try to grab fixtures in a niece/nephew conftest.py file (so to speak) via pytest_plugins, what's the downside to making that work?

At the very least:

@sureshdsk
Copy link

I'm also facing similar issues.

pytest --fixtures lists my fixtures from all django sub apps. but throws error when running tests. configuring pytest_plugins like below worked.

pytest_plugins = [
   "myapp.conftest_a",
   "package_b.conftest_b"
]

Am I doing something wrong?

@Real-Gecko
Copy link

Same issue:

# customers/conftest.py
import pytest

from customers.models import Customer


@pytest.fixture
def customer() -> Customer:
    return Customer.objects.create(
        name="Rocicorp",
        description="",
    )
# companies/conftest.py
import pytest
from customers.models import Customer

from companies.models import Company

pytest_plugins = ["customers.conftest"]


@pytest.fixture
def rocicorp(customer: Customer):
    return Company.objects.create(
        name="Rocicorp",
        company_domain="rocicorp.com",
        email="[email protected]",
        customer=customer,
    )
# companies/tests.py
import pytest


@pytest.mark.django_db
def test_lol(rocicorp: Company):
    company = Company.objects.first()
    assert company.id == rocicorp.id

pytest --fixtures companies

-------------------------- fixtures defined from companies.conftest ---------------------------
rocicorp -- companies/conftest.py:10
    no docstring available


-------------------------- fixtures defined from customers.conftest ---------------------------
customer -- customers/conftest.py:7
    no docstring available


==================================== no tests ran in 0.05s ====================================

pytest companies -k "test_lol"

  @pytest.fixture
  def rocicorp(customer: Customer):
E       fixture 'customer' not found

Any ideas?

@Real-Gecko
Copy link

OK, solved like this: renamed customers/conftest.py to customers/fixtures.py, renamed companies/conftest.py to companies/fixtures.py, created conftest.py in project root:

# project root conftest.py
pytest_plugins = [
    "customers.fixtures",
    "companies.fixtures",
]

@jgarte
Copy link

jgarte commented Mar 15, 2023

Hi, is this the intended way to solve this issue every time?

@cryvate
Copy link
Contributor

cryvate commented Mar 15, 2023

Hi, is this the intended way to solve this issue every time?

From reading this thread and my understanding, yes

@jgarte
Copy link

jgarte commented Mar 15, 2023

Ok, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: fixtures anything involving fixtures directly or indirectly type: question general question, might be closed after 2 weeks of inactivity
Projects
None yet
Development

No branches or pull requests

10 participants