如何在pytest测试方法访问autouse setup fixture内的对象变量
pytest 测试类内fixture创建的资源无法被测试方法访问的修复方案
核心报错原因
- fixture内部定义的
obj是函数级局部变量,作用域仅在fixture函数内部,没有对外传递的话,测试方法没有任何途径可以读取到这个变量。 - 哪怕fixture设置了
autouse=True自动完成setup/teardown流程,只要没有显式把obj通过fixture的返回值暴露,测试方法就拿不到这个串口连接实例。 - 你的原始代码里还有一处基础语法问题:
test_abc方法的定义行末尾缺少冒号,本身也无法正常运行。
正确实现方式
pytest的依赖注入机制只会把fixture的 return/yield 返回值传递给声明依赖该fixture的测试方法,不会主动共享fixture内部的局部变量。要让测试方法访问到初始化的obj,只需要在fixture的yield语句后把这个对象返回出去即可,修正后的完整可运行代码如下:
import pytest class TestSerialPort(): @pytest.fixture(autouse=True) def setupandtear(self, request): # 初始化串口连接对象 obj = connect_serialport() # 通过yield把创建的对象作为fixture返回值暴露 yield obj # teardown阶段执行资源释放 obj.close() def test_abc(self, setupandtear): # 参数setupandtear接收到的就是fixture yield出去的obj对象 serial_conn = setupandtear print(f"串口连接对象的端口:{serial_conn.port}")
新手避坑提示
- 不需要为了拿到
obj单独再写一个新的fixture,直接在原来的setup/teardown fixture里把对象yield出去,同一个fixture就可以同时完成前置初始化、后置资源释放、资源传递三个功能。 - 不要尝试把
obj赋值给测试类的self属性来实现跨方法共享,这种写法在pytest中存在稳定性问题:pytest对测试类的实例化、fixture执行的顺序没有强绑定,很容易出现属性未定义的报错。 - 如果觉得fixture返回值的变量名和fixture本身同名太别扭,像上面代码里那样在测试方法内给返回值起个业务含义清晰的别名即可,不需要修改fixture本身的命名。
内容的提问来源于stack exchange,提问作者Abhi Us
相关产品推荐
相关产品推荐

