在pytest中,如何确保在class级之前调用模块级fixture

In pytest, how to make sure the module level fixture is called before class level

我的 pytest 很旧(版本 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

然而,我得到的订单是:

class start
module start
class end
module end

这不是我想要的。那么编写模块级别 setup/cleanup 夹具的正确方法是什么(并确保它在一切之前进行设置并在一切之后清理)?

pytest 按照在测试文件中编写的顺序处理测试,并在需要时按顺序加载固定装置。请参阅有关 fixtures.

的文档

在您的示例中,pytest 首先从 class 测试开始,然后加载模块依赖项。

如果您想先设置 "module",有多种可能性

a) module_level被class_level用作参数,因此加载在前面(不需要pytestmark)

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) 按照 class-test 的要求使用 @pytestmark,因此它加载在前面

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) 在class-test前面设置一个function-test,这样会先执行module_level

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

在每种情况下,这会在 "class" 前面加载 "module" (pytest-2.8.7):

一)

::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