Pytest, как включить "setup" светильник с областью видимости "class" - PullRequest
2 голосов
/ 19 апреля 2020

Я использую 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

Это работает, однако «настройка» выполняется дважды, т.е. один раз для каждого метода тестирования. Я хотел бы, чтобы он выполнялся только один раз для экземпляра класса, но при изменении области видимости приборов на «класс» я получаю:

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

Так что кажется, что установка больше не запускается вообще. Может кто-нибудь объяснить, почему и предложить решение?

1 Ответ

1 голос
/ 19 апреля 2020

Вы не можете назначить атрибуты экземпляра теста в осциллографе класса. Пока setup является функциональным прибором, все в порядке, потому что оно выполняется для каждого экземпляра TestExample. Как только прибор получает область действия класса, назначение атрибутов экземпляра больше не работает - 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

В последнем примере показано, что устройство класса не является требуется быть частью тестового класса:

@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

    ...
...