pytest fixtures 从外部范围重新定义名称[pylint]

pytest fixtures Redefining name from outer scope [pylint]

我正在学习 pytest 并使用 pylint 对我的代码进行 lint。 但是pylint仍然抱怨:
W0621: Redefining name %r from outer scope (line %s)

对于来自 pytest 的以下示例:

# test_wallet.py

@pytest.fixture
def my_wallet():
    '''Returns a Wallet instance with a zero balance'''
    return Wallet()

@pytest.mark.parametrize("earned,spent,expected", [
    (30, 10, 20),
    (20, 2, 18),
])
def test_transactions(my_wallet, earned, spent, expected):
    my_wallet.add_cash(earned)
    my_wallet.spend_cash(spent)
    assert my_wallet.balance == expected

正在从外部范围重新定义名称 my_wallet

我找到了将 _ 前缀添加到夹具名称的解决方法:_my_wallet.

如果我想将固定装置与函数保存在同一个文件中,最佳做法是什么?

  1. 在所有灯具前添加 _?
  2. 禁用此pylint 检查测试?
  3. 更好的建议?

它通常被禁用 (1, 2)。

有一个 pylint-pytest 插件试图修复一些问题,但错误 W0621 尚未修复。

我刚刚在我的测试文件中禁用了该规则:

# pylint: disable=redefined-outer-name
# ^^^ this
import pytest

@pytest.fixture
def my_wallet():
    '''Returns a Wallet instance with a zero balance'''
    return Wallet()

@pytest.mark.parametrize("earned,spent,expected", [
    (30, 10, 20),
    (20, 2, 18),
])
def test_transactions(my_wallet, earned, spent, expected):
    my_wallet.add_cash(earned)
    my_wallet.spend_cash(spent)
    assert my_wallet.balance == expected

对于@pytest.fixturepytest docs这样说:

If a fixture is used in the same module in which it is defined, the function name of the fixture will be shadowed by the function arg that requests the fixture; one way to resolve this is to name the decorated function fixture_<fixturename> and then use @pytest.fixture(name='<fixturename>').

因此此解决方案与您的选项 1 类似,只是 pytest 作者建议 fixture 函数的描述性稍强一些。所以替换这两行

@pytest.fixture
def my_wallet():

与:

@pytest.fixture(name="my_wallet")
def fixture_my_wallet():

文档中的描述还暗示了另一种解决方案,即将固定装置移动到 conftest.py 中,因此它们与使用固定装置的测试代码不在同一模块中。此位置对于在测试模块之间共享固定装置也很有用。

在 def 中添加 fixture 和 fixture_ 前缀的名称参数。

@pytest.fixture(name="my_wallet")
def fixture_wallet():
    '''Returns a Wallet instance with a zero balance.'''
    return Wallet()

@pytest.mark.parametrize("earned, spent, expected", [
    (30, 10, 20),
    (20, 2, 18),
])
def test_transactions(my_wallet, earned, spent, expected):
    my_wallet.add_cash(earned)
    my_wallet.spend_cash(spent)
    assert my_wallet.balance == expected