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
.
如果我想将固定装置与函数保存在同一个文件中,最佳做法是什么?
- 在所有灯具前添加
_
?
- 禁用此
pylint
检查测试?
- 更好的建议?
有一个 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.fixture
的pytest 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
我正在学习 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
.
如果我想将固定装置与函数保存在同一个文件中,最佳做法是什么?
- 在所有灯具前添加
_
? - 禁用此
pylint
检查测试? - 更好的建议?
有一个 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.fixture
的pytest 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