My pytest is old(version 2.8.3).
pytestmark = pytest.mark.usefixtures("module_level")
@pytest.fixture(scope='module')
def module_level(request):
print("module start")
def fin():
print("module end")
request.addfinalizer(fin)
@pytest.fixture(scope='class')
def class_level(request):
print("class start")
def fin():
print("class end")
request.addfinalizer(fin)
@pytest.mark.usefixtures("class_level")
class TestMyClass:
def test_func(self):
pass
However, the order I got is:
class start
module start
class end
module end
which is not what I want. So what's the right way to write a module level setup/cleanup fixture (and make sure it does the setup before everything and clean up after everything)?
pytest process the tests in the order they are written in a test file and loads the fixtures in the sequence as they are needed. See the documentation about fixtures.
In your example, you pytest starts first with a class test, and the module dependency is loaded afterwards.
There are multiple possibilities if you want to setup the "module" first
a) module_level is used as a parameter by class_level and therefore loaded in front (pytestmark is not needed)
import pytest
@pytest.fixture(scope='module')
def module_level(request):
print("module start")
def fin():
print("module end")
request.addfinalizer(fin)
@pytest.fixture(scope='class')
def class_level(request, module_level):
print("class start")
def fin():
print("class end")
request.addfinalizer(fin)
@pytest.mark.usefixtures("class_level")
class TestMyClass:
def test_func(self):
pass
b) using @pytestmark as as requirement for the class-test and therefore it is loaded in front
import pytest
pytestmark = pytest.mark.usefixtures("module_level")
@pytest.fixture(scope='module')
def module_level(request):
print("module start")
def fin():
print("module end")
request.addfinalizer(fin)
@pytest.fixture(scope='class')
def class_level(request):
print("class start")
def fin():
print("class end")
request.addfinalizer(fin)
@pytest.mark.usefixtures("class_level")
@pytestmark
class TestMyClass:
def test_func(self):
pass
c) setup a function-test in front a class-test, this will execute module_level first
import pytest
pytestmark = pytest.mark.usefixtures("module_level")
@pytest.fixture(scope='module')
def module_level(request):
print("module start")
def fin():
print("module end")
request.addfinalizer(fin)
@pytest.fixture(scope='class')
def class_level(request):
print("class start")
def fin():
print("class end")
request.addfinalizer(fin)
def test_case():
assert True
@pytest.mark.usefixtures("class_level")
class TestMyClass:
def test_func(self):
pass
this loads "module" in front of "class" in each case (pytest-2.8.7):
a)
::TestMyClass::test_func module start
class start
class end
module end
b)
::TestMyClass::test_func module start
class start
class end
module end
c)
::test_case module start
::TestMyClass::test_func class start
class end
module end
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