pytest: Package scoped fixture will not execute teardown
I am experiencing a weird issue: ‘package’ scoped fixture will not execute teardown after last test in package is completed if afformentioned fixture is defined outside of package
Environment
~ python --version
Python 3.8.5
~ pip freeze
allure-pytest==2.8.24
allure-python-commons==2.8.24
assertpy==1.1
attrdict==2.0.1
attrs==20.3.0
bcrypt==3.2.0
cffi==1.14.4
cryptography==3.2.1
cycler==0.10.0
future==0.18.2
iniconfig==1.1.1
kiwisolver==1.3.1
matplotlib==3.3.3
mininet==2.3.0.dev6
more-itertools==8.6.0
numpy==1.19.4
packaging==20.7
paramiko==2.7.2
pexpect==4.8.0
pexpect-serial==0.1.0
Pillow==8.0.1
pluggy==0.13.1
ptyprocess==0.6.0
py==1.9.0
pycparser==2.20
PyNaCl==1.4.0
pyparsing==2.4.7
Pypubsub==4.0.3
pyserial==3.5
pytest==6.2.1
pytest-dependency==0.5.1
pytest-logger==0.5.1
pytest-sugar==0.9.4
python-dateutil==2.8.1
PyYAML==5.3.1
singleton-decorator==1.0.0
six==1.15.0
termcolor==1.1.0
toml==0.10.2
wcwidth==0.2.5
~ uname -a
5.4.0-58-generic #64-Ubuntu SMP Wed Dec 9 08:16:25 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
Example to reproduce
~ tree test
test
├── __init__.py
├── conftest.py
├── sub1
│ └── __init__.py
│ └── test_foo.py
└── sub2
└── __init__.py
└── test_bar.py
2 directories, 3 files
~ cat test/conftest.py
import pytest
@pytest.fixture(scope='package')
def package_scoped():
print('setup')
yield
print('teardown')
~ cat test/sub1/test_foo.py
def test_foo(package_scoped): pass
~ cat test/sub2/test_bar.py
def test_foo(package_scoped): pass
Result
~ pytest test --setup-plan -p no:sugar
=============== test session starts ===============
platform linux -- Python 3.8.5, pytest-6.2.1, py-1.9.0, pluggy-0.13.1
rootdir: /home/hdemchenko/git/uns
plugins: dependency-0.5.1, logger-0.5.1, allure-pytest-2.8.24
collected 2 items
test/sub1/test_foo.py
SETUP P package_scoped
test/sub1/test_foo.py::test_foo (fixtures used: package_scoped)
test/sub2/test_bar.py
test/sub2/test_bar.py::test_foo (fixtures used: package_scoped)
TEARDOWN P package_scoped
=============== no tests ran in 0.01s ===============
If I create two conftest files in each package with the package scoped fixture I intend to use then I can see it behaving as I was expecting. Example:
~ mv test/conftest.py test/sub1/
~ cp test/sub1/conftest.py test/sub2/
~ pytest test --setup-plan -p no:sugar
=============== test session starts ===============
platform linux -- Python 3.8.5, pytest-6.2.1, py-1.9.0, pluggy-0.13.1
rootdir: /home/hdemchenko/git/uns
plugins: dependency-0.5.1, logger-0.5.1, allure-pytest-2.8.24
collected 2 items
test/sub1/test_foo.py
SETUP P package_scoped
test/sub1/test_foo.py::test_foo (fixtures used: package_scoped)
TEARDOWN P package_scoped
test/sub2/test_bar.py
SETUP P package_scoped
test/sub2/test_bar.py::test_foo (fixtures used: package_scoped)
TEARDOWN P package_scoped
=============== no tests ran in 0.01s ===============
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 1
- Comments: 18 (5 by maintainers)
Commits related to this issue
- Define package-scoped fixtures and add missing __init__.py files * Fixtures defined in a test package's conftest.py should not be session-scoped. Change the scope to "package". * Due to a bug in py... — committed to xcp-ng/xcp-ng-tests by stormi 2 years ago
- Define package-scoped fixtures and add missing __init__.py files * Fixtures defined in a test package's conftest.py should not be session-scoped. Change the scope to "package". * Due to a bug in py... — committed to xcp-ng/xcp-ng-tests by stormi 2 years ago
- Define package-scoped fixtures and add missing __init__.py files * Fixtures defined in a test package's conftest.py should not be session-scoped. Change the scope to "package". * Due to a bug in py... — committed to xcp-ng/xcp-ng-tests by stormi 2 years ago
- Define package-scoped fixtures and add missing __init__.py files * Fixtures defined in a test package's conftest.py should not be session-scoped. Change the scope to "package". * Due to a bug in py... — committed to xcp-ng/xcp-ng-tests by stormi 2 years ago
- Define package-scoped fixtures and add missing __init__.py files * Fixtures defined in a test package's conftest.py should not be session-scoped. Change the scope to "package". * Due to a bug in py... — committed to xcp-ng/xcp-ng-tests by stormi 2 years ago
- Define package-scoped fixtures and add missing __init__.py files * Fixtures defined in a test package's conftest.py should not be session-scoped. Change the scope to "package". * Due to a bug in py... — committed to xcp-ng/xcp-ng-tests by stormi 2 years ago
- Define package-scoped fixtures and add missing __init__.py files * Fixtures defined in a test package's conftest.py should not be session-scoped. Change the scope to "package". * Due to a bug in py... — committed to xcp-ng/xcp-ng-tests by stormi 2 years ago
- Define package-scoped fixtures and add missing __init__.py files * Fixtures defined in a test package's conftest.py should not be session-scoped. Change the scope to "package". * Due to a bug in py... — committed to xcp-ng/xcp-ng-tests by stormi 2 years ago
- Define package-scoped fixtures and add missing __init__.py files * Fixtures defined in a test package's conftest.py should not be session-scoped. Change the scope to "package". * Due to a bug in py... — committed to xcp-ng/xcp-ng-tests by stormi 2 years ago
- Define package-scoped fixtures and add missing __init__.py files * Fixtures defined in a test package's conftest.py should not be session-scoped. Change the scope to "package". * Due to a bug in py... — committed to xcp-ng/xcp-ng-tests by stormi 2 years ago
Ok, I think I finally get where the confusion comes from.
Consider following:
My assumptions are:
What I think is happening: the pytest finds the declaration of the “foxtrot” fixture and assumes it applies to the boundaries of the “papa” package but not to the sub-packages (“alpha” and “bravo”)
Marking as fixed in pytest 8.0.0 (#11646), let me know if not.
@bluetech, thanks I’ll keep an eye on the progress.
Here’s a quick tip on workaround for other people who might stumble upon this issue (it is easy although not very beatiful) All you need to do is:
conftest
file in each package you want to use the fixtureconftest
fileThanks for the details @hennadii-demchenko. I agree with your intuition here. I think the package scope and/or conftest handling is quite buggy. There’s also some related discussion in #7777 (in the sense that it affects the behavior here).
I’m marking this as a bug. Personally I do plan to dig into this more soon.
And to proove my point further - another way to get expected (at least by me) behavior is:
test/conftest.py
the same as in reporttest/sub1/conftest.py
andtest/sub2/conftest.py
simply import fixture and nothing else