You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pytest中class作用域setup fixture使用异常问题排查与解决

问题原因分析

当你把add_info fixture的作用域改为class后,pytest会在测试类级别执行这个fixture,而非每个测试方法对应的实例级别。这时候fixture中的self指代的是TestExample这个类本身,不是每个测试方法运行时创建的类实例。

你在fixture里设置的self.c其实是给TestExample类添加了一个类属性,但测试方法里的self是类的实例,实例默认不会直接继承这个类属性,所以才会抛出AttributeError: 'TestExample' object has no attribute 'c'。


解决方案

下面提供两种可行的解决思路:

方案1:在测试方法中显式访问类属性

既然c已经被设置为类属性,直接通过类本身或者type(self)来访问它就行:

import pytest

@pytest.fixture(scope='module')
def fixture_a():
    return 2

class TestExample:
    b = 1

    @pytest.fixture(autouse=True, scope='class')
    def add_info(self, fixture_a):
        # 这里的self是TestExample类本身
        self.c = self.b * fixture_a

    def test_foo(self):
        # 通过type(self)访问类属性c
        assert type(self).c + self.b == 3

    def test_bar(self):
        # 或者直接通过类名访问
        assert TestExample.c * self.b == 2

方案2:用request.cls明确操作测试类

更清晰的方式是借助pytest的request fixture获取测试类,避免self带来的歧义:

import pytest

@pytest.fixture(scope='module')
def fixture_a():
    return 2

class TestExample:
    b = 1

    @pytest.fixture(autouse=True, scope='class')
    def add_info(self, fixture_a, request):
        # 用request.cls直接获取当前测试类,设置类属性
        request.cls.c = self.b * fixture_a

    def test_foo(self):
        assert type(self).c + self.b == 3

    def test_bar(self):
        assert type(self).c * self.b == 2

这两种方案都能保证add_info只在类初始化时执行一次,同时测试方法能正确访问到c的值。


内容的提问来源于stack exchange,提问作者Hagobert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 10:57:28