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

Hao*_*hen 5 python fixture pytest

我的 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
Run Code Online (Sandbox Code Playgroud)

但是,我得到的订单是:

class start
module start
class end
module end
Run Code Online (Sandbox Code Playgroud)

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

and*_*pei 5

pytest 按照写入测试文件的顺序处理测试,并根据需要按顺序加载设备。请参阅有关装置的文档。

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

如果您想先设置“模块”,有多种可能性

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
Run Code Online (Sandbox Code Playgroud)

b) 使用@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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

在每种情况下(pytest-2.8.7),这会在“类”之前加载“模块”:

一种)

::TestMyClass::test_func module start
class start
class end
module end
Run Code Online (Sandbox Code Playgroud)

b)

::TestMyClass::test_func module start
class start
class end
module end
Run Code Online (Sandbox Code Playgroud)

C)

::test_case module start
::TestMyClass::test_func class start
class end
module end
Run Code Online (Sandbox Code Playgroud)