How to share object from fixture to all tests using pytest?

My recommendation would to add the fixture to conftest.py and make sure to return the object you want to produce from the fixture.

As noted, this makes "autouse" kind of useless.

In the root directory for your tests, add the fixture to a file named conftest.py:

@pytest.fixture(scope='session', autouse=True)
def someobj(request):
    return SomeObj()

Any test file beneath the root file will have access to this fixture (for example test_foo.py):

def test_foo(someobj):
    assert isinstance(someobj, SomeObj)

Another approach, would be to use a global variable defined in the same test or imported from a module.

For example in conftest.py:

someobj = None
@pytest.fixture(scope='session', autouse=True)
def prep_someobj(request):
    someobj = SomeObj()

Then in your test:

from . import conftest

def test_foo():
    assert isinstance(conftest.someobj, SomeObj)

In my opinion this is less readable and more cumbersome than the first method.


Another possibility is to wrap your tests in a class and use class variables to only define the object instance once. This assumes you are able to wrap all tests in a single class and so this answer may address a less general, but similar use case. For example,

class SomeObj():
    """This object definition may exist in another module and be imported."""
    def __init__(self):
        self.x = 5

    def do_something_fancy(self, y):
        return self.x * y


class TestX():
    # Object instance to share across tests
    someobj = SomeObj()

    def test_x(self):
        assert TestX.someobj.x == 5

    def test_fancy(self):
        fancy_factor = 10
        result = TestX.someobj.do_something_fancy(fancy_factor)
        assert result == 50

A more general pattern for this is to return locals() at the end of your conftest and you'll be able to easily reference anything created in the fixture.

conftest.py

@pytest.fixture(scope='session')
def setup_func(request):
    obj1 = SomeObj()
    obj2 = SomeObj()

    return locals()

test_stuff.py

def test_one(setup_func):
   setup_func['obj1'].do_something_fancy()

def test_two(setup_func):
   setup_func['obj2'].do_something_fancy()

Tags:

Python

Pytest