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
相关产品推荐
相关产品推荐

