python - Pytest 如何包含范围为 "setup"的 "class" fixture

标签 python pytest fixtures

我正在使用 pytest 并且通常将我的测试分组为我包中模块的“镜像”。为了在我的测试模块中有一个良好的结构,我喜欢将一些测试分组到类中,即使我使用的是 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

这有效,但是“设置”执行两次,即每个测试方法执行一次。我希望每个类实例只执行一次,但是当将 fixture 范围更改为“类”时,我得到:
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

因此,似乎根本不再运行安装程序。有人可以解释原因并提供解决方案吗?

最佳答案

您不能在类范围的装置中分配给测试实例属性。只要setup是一个函数范围的fixture,一切都很好,因为它为每个TestExample 执行实例。一旦 fixture 获得类范围,分配给实例属性就不再起作用 - setup()test_foo()在不同的地方被调用 TestExample实例。诉诸明确的类范围属性,例如

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

最后一个示例显示类范围的 fixture 不需要成为测试类的一部分:
@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

    ...

关于python - Pytest 如何包含范围为 "setup"的 "class" fixture ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61305801/

相关文章:

ruby-on-rails - 对 Rails 初始值设定项中的 fixture 数据的依赖

python - h2o python 平衡类

Python doctests 和 unicode

python - Pytest monkeypatch 不适用于导入的函数

macos - 在终端中更改 Pytest 颜色输出

django - 在 Django 单元测试中加载固定装置

python - 两个字典的合并和求和

python - django allauth登录测试无法正确登录

pytest - py.test 给出 Coverage.py 警告 : Module sample. py 从未导入

python - Django fixtures 以默认值保存