In pytest fixture scope, I noted that you can specify session scope so that a fixture will only run once per test session and be available across multiple test functions, classes, and modules.

In this post, I’m going to show a simple example so you can see it in action.

Here’s the table from the previous post:

A separate file for fixtures, conftest.py

With function, class, and module scope, it is completely reasonable for the fixture code to be in the same file as the tests.
But now suddenly, with session, that doesn’t make sense anymore.

We can put them in conftest.py. This is a special named file that pytest looks for.
[The documentation][8] says that it’s for local plugins, but we can use it for local fixtures as well. See the [pytest.org site][8] for placement and scope of conftest.py.

Simple example of session scope fixtures

I think it’s clearest to just see this in action.

I’ve got 4 files:

  • conftest.py
  • test_alpha.py
  • test_beta.py
  • test_gamma.py

conftest.py

  • 2 fixtures
  • my_own_session_fixture(), an autouse fixture with session scope
  • some_resource(), a normal non-autouse fixture with session scope
import pytest

@pytest.fixture(scope="session", autouse=True)
def my_own_session_fixture(request):
    print('\n[setup] my_own_session_fixture()')
    yield
    print('[teardown] my_own_session_fixture()')


@pytest.fixture(scope="session")
def some_resource(request):
    print('\n[setup] some_resource()')
    yield
    print('[teardown] some_resource()')

test_alpha.py

  • 2 simple test functions
  • test_alpha_1, has no named fixtures
  • test_alpha_2, has one named fixture, some_resource
def test_alpha_1():
    print('\nIn test_alpha_1()')

def test_alpha_2(some_resource):
    print('\nIn test_alpha_2()')

test_beta.py

  • similar to test_alpha.py, but with unittest based tests
import pytest
import unittest

class BetaTest(unittest.TestCase):
    def test_unit_beta_1(self):
        print('\nIn test_unit_beta_1()')

    @pytest.mark.usefixtures('some_resource')    
    def test_unit_beta_2(self):
        print('\nIn test_unit_beta_2()')

test_gamma.py

  • similar to test_alpha.py, but with class based tests
class TestGamma:
    def test_gamma_1(self):
        print('\nIn test_gamma_1()')

    def test_gamma_2(self, some_resource):
        print('\nIn test_gamma_2()')

Output

Run with pytest -s -v:

$ pytest -s -v
================== test session starts ==================
collected 6 items                                       

test_alpha.py::test_alpha_1 
[setup] my_own_session_fixture()

In test_alpha_1()
PASSED
test_alpha.py::test_alpha_2 
[setup] some_resource()

In test_alpha_2()
PASSED
test_beta.py::BetaTest::test_unit_beta_1 
In test_unit_beta_1()
PASSED
test_beta.py::BetaTest::test_unit_beta_2 
In test_unit_beta_2()
PASSED
test_gamma.py::TestGamma::test_gamma_1 
In test_gamma_1()
PASSED
test_gamma.py::TestGamma::test_gamma_2 
In test_gamma_2()
PASSED[teardown] some_resource()
[teardown] my_own_session_fixture()

=================== 6 passed in 0.01s ===================

Perhaps more of an example than necessary.
However, we can see that we can use fixtures defined in a conftest.py file from several test files.

Taking it further

The code I’ve shown is for simple run at the beginning and end type fixtures.
However, there’s more you can do with session fixtures.
The pytest.org site has a cool example, A session-fixture which can look at all collected tests.