Pytest 如何在范围 "class" 中包含 "setup" 夹具
Pytest how to include "setup" fixture with scope "class"
我正在使用 pytest,通常将我的测试分组为包中模块的 "mirror"。为了在我的测试模块中有一个好的结构,我喜欢将一些测试分组在 classes 中,即使我使用的是 pytest。我 运行 遇到了固定装置范围级别的问题。考虑这个最小的例子:
import pytest
@pytest.fixture(scope='module')
def fixture_a():
return 2
class TestExample:
b = 1.
@pytest.fixture(autouse=True, scope='function')
def add_info(self, fixture_a):
self.c = self.b * fixture_a
def test_foo(self):
assert self.c + self.b == 3
def test_bar(self):
assert self.c * self.b == 2
这有效,但是 'setup' 执行了两次,即每个测试方法执行一次。我希望每个 class 实例只执行一次,但是当将灯具范围更改为 'class' 时,我得到:
FAILED [ 50%]
tests\tests_simple\test_library\test_example_sof.py:15 (TestExample.test_foo)
self = <test_example_sof.TestExample object at 0x0000019A8C9C9CC0>
def test_foo(self):
> assert self.c + self.b == 3
E AttributeError: 'TestExample' object has no attribute 'c'
test_example_sof.py:17: AttributeError
FAILED [100%]
tests\tests_simple\test_library\test_example_sof.py:18 (TestExample.test_bar)
self = <test_example_sof.TestExample object at 0x0000019A8C9C9EF0>
def test_bar(self):
> assert self.c * self.b == 2
E AttributeError: 'TestExample' object has no attribute 'c'
test_example_sof.py:20: AttributeError
Assertion failed
所以似乎安装程序不再是 运行。有人可以解释原因并提供解决方案吗?
您不能在 class 范围的夹具中分配测试实例属性。只要 setup
是一个函数范围的固定装置,一切都很好,因为它是为每个 TestExample
实例执行的。一旦 fixture 获得 class 范围,分配给实例属性就不再起作用 - setup()
和 test_foo()
在不同的 TestExample
实例上被调用。求助于显式 class 范围的属性,例如
class TestExample:
b = 1.0
@pytest.fixture(autouse=True, scope='class')
def setup(self, fixture_a):
self.__class__.c = self.b * fixture_a
或
class TestExample:
b = 1.0
@staticmethod
@pytest.fixture(autouse=True, scope='class')
def setup(fixture_a):
TestExample.c = TestExample.b * fixture_a
或
class TestExample:
b = 1.0
@pytest.fixture(autouse=True, scope='class')
def setup(self, request, fixture_a):
request.cls.c = request.cls.b * fixture_a
最后一个示例表明 class 范围的夹具不需要成为测试的一部分 class:
@pytest.fixture(autouse=True, scope='class')
def setup_cls(request, fixture_a):
request.cls.c = request.cls.b * fixture_a
class TestExample:
b = 1.0
...
我正在使用 pytest,通常将我的测试分组为包中模块的 "mirror"。为了在我的测试模块中有一个好的结构,我喜欢将一些测试分组在 classes 中,即使我使用的是 pytest。我 运行 遇到了固定装置范围级别的问题。考虑这个最小的例子:
import pytest
@pytest.fixture(scope='module')
def fixture_a():
return 2
class TestExample:
b = 1.
@pytest.fixture(autouse=True, scope='function')
def add_info(self, fixture_a):
self.c = self.b * fixture_a
def test_foo(self):
assert self.c + self.b == 3
def test_bar(self):
assert self.c * self.b == 2
这有效,但是 'setup' 执行了两次,即每个测试方法执行一次。我希望每个 class 实例只执行一次,但是当将灯具范围更改为 'class' 时,我得到:
FAILED [ 50%]
tests\tests_simple\test_library\test_example_sof.py:15 (TestExample.test_foo)
self = <test_example_sof.TestExample object at 0x0000019A8C9C9CC0>
def test_foo(self):
> assert self.c + self.b == 3
E AttributeError: 'TestExample' object has no attribute 'c'
test_example_sof.py:17: AttributeError
FAILED [100%]
tests\tests_simple\test_library\test_example_sof.py:18 (TestExample.test_bar)
self = <test_example_sof.TestExample object at 0x0000019A8C9C9EF0>
def test_bar(self):
> assert self.c * self.b == 2
E AttributeError: 'TestExample' object has no attribute 'c'
test_example_sof.py:20: AttributeError
Assertion failed
所以似乎安装程序不再是 运行。有人可以解释原因并提供解决方案吗?
您不能在 class 范围的夹具中分配测试实例属性。只要 setup
是一个函数范围的固定装置,一切都很好,因为它是为每个 TestExample
实例执行的。一旦 fixture 获得 class 范围,分配给实例属性就不再起作用 - setup()
和 test_foo()
在不同的 TestExample
实例上被调用。求助于显式 class 范围的属性,例如
class TestExample:
b = 1.0
@pytest.fixture(autouse=True, scope='class')
def setup(self, fixture_a):
self.__class__.c = self.b * fixture_a
或
class TestExample:
b = 1.0
@staticmethod
@pytest.fixture(autouse=True, scope='class')
def setup(fixture_a):
TestExample.c = TestExample.b * fixture_a
或
class TestExample:
b = 1.0
@pytest.fixture(autouse=True, scope='class')
def setup(self, request, fixture_a):
request.cls.c = request.cls.b * fixture_a
最后一个示例表明 class 范围的夹具不需要成为测试的一部分 class:
@pytest.fixture(autouse=True, scope='class')
def setup_cls(request, fixture_a):
request.cls.c = request.cls.b * fixture_a
class TestExample:
b = 1.0
...