I want to have a "global fixture" (in pytest they could also be called "session scoped fixtures") which does some expensive environment setup, like typically preparing a resource, which is then reused across test modules. The setup is something like this,
would have a fixture doing something expensive, like starting up a Docker container, MySQL server, etc.
@pytest.yield_fixture(scope="session")
def test_server():
start_docker_container(port=TEST_PORT)
yield TEST_PORT
stop_docker_container()
would use the server,
def test_foo(test_server): ...
would use the same server
def test_foo(test_server): ...
It seems that pytest has support for this via scope="session"
, but I can't figure out how to make the actual imports work. The current setup will given an error message like,
fixture 'test_server' not found
available fixtures: pytestconfig, ...
use 'py.test --fixtures [testpath] ' for help on them
fixtures have explicit names and are activated by declaring their use from test functions, modules, classes or whole projects. fixtures are implemented in a modular manner, as each fixture name triggers a fixture function which can itself use other fixtures.
Additionally, if you wish to display a list of fixtures for each test, try the --fixtures-per-test flag.
To access the fixture function, the tests have to mention the fixture name as input parameter. Pytest while the test is getting executed, will see the fixture name as input parameter. It then executes the fixture function and the returned value is stored to the input parameter, which can be used by the test.
A session-scoped fixture effectively has access to all collected test items. Here is an example of a fixture function which walks all collected tests and looks if their test class defines a callme method and calls it: # content of conftest.py import pytest @pytest.
There is a convention in pytest which uses the special file named conftest.py
and contains session fixtures.
I have extracted two very simple examples to give a quick start. They do not use classes.
Everything taken from http://pythontesting.net/framework/pytest/pytest-session-scoped-fixtures/
Example 1:
The fixture is not executed unless supplied as an argument to a test_*
function. The fixture some_resource
is executed prior to calling the referencing function, in this case test_2
. The finalizer on the other hand is executed at the end.
conftest.py:
import pytest
@pytest.fixture(scope="session")
def some_resource(request):
print('\nSome resource')
def some_resource_fin():
print('\nSome resource fin')
request.addfinalizer(some_resource_fin)
test_a.py:
def test_1():
print('\n Test 1')
def test_2(some_resource):
print('\n Test 2')
def test_3():
print('\n Test 3')
Result:
$ pytest -s
======================================================= test session starts ========================================================
platform linux -- Python 3.4.3 -- py-1.4.26 -- pytest-2.7.0
rootdir: /tmp/d2, inifile:
collected 3 items
test_a.py
Test 1
.
Some recource
Test 2
.
Test 3
.
Some resource fin
Example 2:
Here the fixture is configured with autouse=True
, so it is executed once at the beginning of the session, and it does not have to be referenced. Its finalizer is executed at the end of the session.
conftest.py:
import pytest
@pytest.fixture(scope="session", autouse=True)
def auto_resource(request):
print('\nSome resource')
def auto_resource_fin():
print('\nSome resource fin')
request.addfinalizer(auto_resource_fin)
test_a.py:
def test_1():
print('\n Test 1')
def test_2():
print('\n Test 2')
def test_3():
print('\n Test 3')
Result:
$ pytest -s
======================================================= test session starts ========================================================
platform linux -- Python 3.4.3 -- py-1.4.26 -- pytest-2.7.0
rootdir: /tmp/d2, inifile:
collected 3 items
test_a.py
Some recource
Test 1
.
Test 2
.
Test 3
.
Some resource fin
Okay, I think I got it ... the solution is to name shared_env.py
conftest.py
See this good blog post for details [ http://pythontesting.net/framework/pytest/pytest-session-scoped-fixtures/ ]. It has a working example, so hopefully not too hard to work backwards from there if necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With