So, I just lost a day trying to find out why py.test
isn't executing my autouse, session-scoped setup and teardown fixtures. In the end I stumbled over (hat tip to this SO comment!) this little tidbit in the plugins documentation:
Note that conftest.py files from sub directories are by default not loaded at tool startup.
In my project, I got my py.test files (conftest.py
and tests files) in a tests/
subdirectory, which seems like a pretty standard setup. If I run py.test
in the tests directory, everything runs correctly. If I run py.test
in the project root directory, the tests still run, but the setup/teardown routines never get executed.
Questions:
- What's the "canonical" way to enable users to correctly run tests from the project root dir? Putting
conftest.py
in the root directory feels strange to me, cause I feel all tests-related files should remain in thetests
subdirectory. - Why (design-wise) aren't
conftest.py
's in subdirectories not loaded by default? I find this behaviour curious to say the least, considering that tests in subdirectories are discovered by default, so there seems to be very little additional effort involved in finding conftest files, too. - Lastly, how can I have
conftest.py
in subdirectories load (i.e. change away from the default)? I couldn't find this in the docs. I'd like to avoid additional console arguments if possible, so can I put anything in a config file or whatnot?
Any insight and tips are much appreciated, I feel that I lost/wasted wayy to much time diagnosing this when I could have written tests for my project. :-(
Minimal example:
# content of tests/conftest.py
# adapted from http://pytest.org/latest/example/special.html
import pytest
def tear_down():
print "\nTEARDOWN after all tests"
@pytest.fixture(scope="session", autouse=True)
def set_up(request):
print "\nSETUP before all tests"
request.addfinalizer(tear_down)
test file:
# content of tests/test_module.py
class TestClassA:
def test_1(self):
print "test A1 called"
def test_2(self):
print "test A2 called"
class TestClassB:
def test_1(self):
print "test B1 called"
Console output:
pytest_experiment$ py.test -s
======================================================== test session starts =========================================================
platform linux2 -- Python 2.7.4 -- pytest-2.3.2
plugins: cov
collected 3 items
tests/test_module.py test A1 called
.test A2 called
.test B1 called
.
====================================================== 3 passed in 0.02 seconds ======================================================
pytest_experiment$ cd tests/
pytest_experiment/tests$ py.test -s
======================================================== test session starts =========================================================
platform linux2 -- Python 2.7.4 -- pytest-2.3.2
plugins: cov
collected 3 items
test_module.py
SETUP before all tests
test A1 called
.test A2 called
.test B1 called
.
TEARDOWN after all tests
====================================================== 3 passed in 0.02 seconds ======================================================