【问题标题】:pytest fixture not found on a simple decorator, only on Python 3在简单的装饰器上找不到 pytest 固定装置,仅在 Python 3 上
【发布时间】:2020-05-24 19:34:29
【问题描述】:

Pytest 在 Python 3.7 上失败了以下测试用例,并出现“fixture 'func' not found”。在 Python 2.7 上,相同的代码成功。在这两种情况下,都使用 pytest 4.6.9:

pytest_decorator_issue/test_issue.py的内容:

import functools

def my_decorator(func):

    def wrapper_func(*args, **kwargs):
        # do something on entry
        ret = func(*args, **kwargs)
        # do something on exit
        return ret

    return functools.update_wrapper(wrapper_func, my_decorator)

@my_decorator
def test_bla():
    # perform some test
    pass

在 Python 3.7 上调用 pytest:

$ pytest pytest_decorator_issue -vv
=============== ... test session starts ...
platform darwin -- Python 3.7.5, pytest-4.6.9, py-1.8.0, pluggy-0.13.1 -- .../virtualenvs/pywbem37/bin/python
cachedir: .pytest_cache
rootdir: ...
plugins: requests-mock-1.7.0, cov-2.8.1
collected 1 item                                                                                                                                         

pytest_decorator_issue/test_issue.py::test_bla ERROR                                                                                   [100%]

============ ...  ERRORS ...
____________ ...  ERROR at setup of test_bla ...
file .../pytest_decorator_issue/test_fixture_issue.py, line 3
  def my_decorator(func):
E       fixture 'func' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, cov, doctest_namespace, monkeypatch, no_cover, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, requests_mock, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

.../pytest_decorator_issue/test_fixture_issue.py:3
============== ...  1 error in 0.01 seconds =================================================================

Pytest 在看到装饰器函数的参数时显然决定寻找一个名为“func”的夹具,但为什么它在 Python 2.7 上不这样做,我怎么能在 pytest 测试中拥有像这样的简单装饰器功能?

只是为了比较版本,在 Python 2,7 上,相关的 pytest 输出是:

platform darwin -- Python 2.7.16, pytest-4.6.9, py-1.8.0, pluggy-0.13.1 -- .../virtualenvs/pywbem27/bin/python
cachedir: .pytest_cache
rootdir: ...
plugins: requests-mock-1.7.0, cov-2.8.1
collected 1 item                                        

更新:

我刚刚发现,当使用 functools.wraps 装饰器而不是 functools.update_wrapper() 时,pytest 在 Python 2.7 和 3.7 上都很满意:

def my_decorator(func):

    @functools.wraps(func)
    def wrapper_func(*args, **kwargs):
        # do something on entry
        ret = func(*args, **kwargs)
        # do something on exit
        return ret

    return wrapper_func

谁能解释一下?

【问题讨论】:

  • 我认为您对update_wrapper 的调用中的第二个参数必须是func 而不是my_decorator。不过,不确定为什么这在 Python 2 下有效。
  • 非常感谢!!事实证明你就在那里。按照您的建议更正第二个参数修复了所有情况。随时重新发布您的评论作为对这个问题的回答。

标签: python pytest python-decorators


【解决方案1】:

您对update_wrapper 的调用中的第二个参数必须是func 而不是my_decorator

def my_decorator(func):

    def wrapper_func(*args, **kwargs):
        # do something on entry
        ret = func(*args, **kwargs)
        # do something on exit
        return ret

    return functools.update_wrapper(wrapper_func, func)

不知道为什么这在 Python 2 下有效。

【讨论】:

  • 非常感谢!!事实证明你就在那里。按照您的建议更正第二个参数修复了所有情况。
猜你喜欢
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 2018-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多