Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get py.test to recognize conftest.py in a subdirectory?

Tags:

python

pytest

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 the tests 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 ======================================================
like image 978
Christoph Avatar asked Sep 01 '13 13:09

Christoph


People also ask

Where do I put Conftest py?

You can put fixtures into individual test files, but to share fixtures among multiple test files, you need to use a conftest.py file somewhere centrally located for all of the tests. For the Tasks project, all of the fixtures will be in tasks_proj/tests/conftest.py. From there, the fixtures can be shared by any test.

What is Conftest py in pytest?

conftest.py is where you setup test configurations and store the testcases that are used by test functions. The configurations and the testcases are called fixture in pytest.

What is Confest py file?

The conftest.py file serves as a means of providing fixtures for an entire directory. Fixtures defined in a conftest.py can be used by any test in that package without needing to import them (pytest will automatically discover them).

How does pytest load plugins?

pytest loads plugin modules at tool startup in the following way: by scanning the command line for the -p no:name option and blocking that plugin from being loaded (even builtin plugins can be blocked this way). This happens before normal command-line parsing. by loading all builtin plugins.


1 Answers

After some help on the #pylib IRC channel, it turns out that this was a bug that has been fixed in py.test 2.3.4.

like image 105
Christoph Avatar answered Oct 02 '22 11:10

Christoph