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

Python3.7中Pytest提示‘fixture func未找到’的装饰器问题

为什么Python 3.7下pytest报"fixture 'func' not found",Python 2.7却正常?

问题根源:你写错了functools.update_wrapper的参数

先直接说核心问题:你的装饰器代码里,functools.update_wrapper(wrapper_func, my_decorator)这一行犯了个低级错误——第二个参数应该传入被装饰的原始测试函数func,而不是装饰器本身my_decorator。

为什么Python版本间会有差异?

  • Python 2.7环境:pytest 4.6.9在解析测试函数时,可能没有严格校验被装饰后函数的__wrapped__属性或签名信息。即使你错误地把wrapper的元数据关联到了my_decorator,pytest也没去解析这个装饰器函数的参数(也就是func),所以没触发fixture找不到的错误。
  • Python 3.7环境:Python 3对functools.update_wrapper的元数据复制更彻底,包括函数签名相关的属性。当你把wrapper关联到my_decorator后,pytest会识别到这个"测试函数"的签名是my_decorator(func),误以为test_bla需要一个名为func的fixture,于是抛出错误。

正确的测试函数装饰器写法

有两种可靠的方式,都能让你的装饰器在两个Python版本下兼容:

方式1:修正update_wrapper的参数

import functools
def my_decorator(func):
    def wrapper_func(*args, **kwargs):
        # 前置操作
        ret = func(*args, **kwargs)
        # 后置操作
        return ret
    # 第二个参数改为原始函数func,正确关联元数据
    return functools.update_wrapper(wrapper_func, func)

@my_decorator
def test_bla():
    pass

方式2:使用@functools.wraps(func)(更简洁)

这也是你发现的可行方案,本质上functools.wraps就是update_wrapper的语法糖,自动帮你把wrapper的元数据关联到原始函数:

import functools
def my_decorator(func):
    @functools.wraps(func)
    def wrapper_func(*args, **kwargs):
        # 前置操作
        ret = func(*args, **kwargs)
        # 后置操作
        return ret
    return wrapper_func

@my_decorator
def test_bla():
    pass

这两种写法的核心都是让wrapper函数的元数据正确指向原始测试函数,这样pytest就能正常识别测试函数的签名,不会误判需要额外的fixture。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 15:27:27