在 pytest fixture 中设置 class 属性

Set a class attribute in pytest fixture

我正在为 pytest 进行测试 class,我想设置一个 class 属性 a,它将用于多个测试方法。为此,我使用了一个夹具 set_a,它会自动启动 autouse=True,并且只为 class (scope='class') 调用一次,因为设置 a是昂贵的。这是我的代码:

import pytest
import time


class Test:

    @pytest.fixture(scope='class', autouse=True)
    def set_a(self):
        print('Setting a...')
        time.sleep(5)
        self.a = 1

    def test_1(self):
        print('TEST 1')
        assert self.a == 1

但是测试失败并出现以下错误:

========================================================================= FAILURES ==========================================================================
________________________________________________________________________ Test.test_1 ________________________________________________________________________

self = <tests.test_file.Test object at 0x116d953a0>

    def test_1(self):
        print('TEST 1')
>       assert self.a == 1
E       AttributeError: 'Test' object has no attribute 'a'

tests/test_file.py:15: AttributeError
------------------------------------------------------------------- Captured stdout setup -------------------------------------------------------------------
Setting a...
------------------------------------------------------------------- Captured stdout call --------------------------------------------------------------------
TEST 1

即使调用了 set_a,看起来 a 也没有设置,就像在执行测试时创建了 class 的新实例一样。

如果我将夹具范围更改为 function,效果很好,但我不想为每个测试设置 a

知道这里有什么问题吗?

你不应该设置范围,因为你已经在 class。

class Test:
    @pytest.fixture(autouse=True)
    def set_a(self):
        print("Setting a...")
        time.sleep(5)
        self.a = 1

    def test_1(self):
        print("TEST 1")
        assert self.a == 1

这是您应该如何使用 scope=class,这意味着它适用于您模块中的任何 class:

@pytest.fixture(scope="class", autouse=True)
def a(request):
    print("Setting a...")
    time.sleep(5)
    request.cls.a = 1


class Test:
    def test_1(self):
        print("TEST 1")
        assert self.a == 1

如果该值永远不会改变,另一个选项是在测试方法之外定义它 --

import pytest
import time


class Test:
    a = 1

    def test_1(self):
        print('TEST 1')
        assert self.a == 1