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
11.96k stars 2.66k forks source link

fixture was not found when defined in a test file but discovered twice #6266

Open felixonmars opened 4 years ago

felixonmars commented 4 years ago

I have created a minimal case:

$ tree .
.
├── dir1
│   └── dir2 -> ../dir2
└── dir2
    └── test_fixture.py
$ cat dir2/test_fixture.py
import pytest

@pytest.fixture
def i_am_a_fixture():
    return

def test_fixture(i_am_a_fixture):
    pass
$ pytest
======================= test session starts ========================
platform linux -- Python 3.8.0, pytest-4.6.6, py-1.8.0, pluggy-0.13.1
rootdir: /tmp/test
collected 2 items

dir1/dir2/test_fixture.py .                                  [ 50%]
dir2/test_fixture.py E                                       [100%]

============================== ERRORS ==============================
__________________ ERROR at setup of test_fixture __________________
file /tmp/test/dir1/dir2/test_fixture.py, line 9
  def test_fixture(i_am_a_fixture):
E       fixture 'i_am_a_fixture' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

/tmp/test/dir1/dir2/test_fixture.py:9
================ 1 passed, 1 error in 0.01 seconds =================

The error is present in latest 5.2.4 version as well.

gftea commented 4 years ago

for a fixture shared by multiple modules, recommend to put your fixture in conftest.py in your parent module.

I think this is not a bug. the fixture is found first in "./dir1/dir2", so it is bound to namespace "./dir1/dir2", and you folder has no __init__.py, so the fixture cannot be found in "./dir2"

add __init__.py to dir1 and dir2, then it is OK.

.
├── dir1
│   ├── __init__.py
│   └── dir2 -> ../dir2
├── dir2
│   ├── __init__.py
│   └── test_fixture.py
felixonmars commented 4 years ago

I see. I encountered this when running the test suite for another project, so I excluded the actually duplicated tests to workaround. Just thought this is something that pytest itself might want to address...