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 scopesome_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.
This post is part of a series on pytest fixtures
- pytest fixtures nuts and bolts
- pytest xunit-style fixtures
- Basic pytest fixtures example
- Using pytest fixtures by naming them
- Using pytest autouse fixtures
- Using pytest fixtures with mark.usefixtures
- pytest fixture return value
- pytest fixture teardown
- pytest fixture scope
- Parametrizing pytest fixtures with param
- Using multiple pytest fixtures
- Modularity: pytest fixtures using other fixtures
- pytest session scoped fixtures - this post
- Mixing pytest fixture scope)