Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pytest fixtures Redefining name from outer scope [pylint]

I'm learning pytest and I lint my code with pylint. But pylint still complaints about:
W0621: Redefining name %r from outer scope (line %s)

for the following example from 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 

Redefining name my_wallet from outer scope.

I found workaround to add _ prefix to the fixture name: _my_wallet.

What would be the best practice if I want to keep fixtures in same file as functions?

  1. Prepend all fixtures with _?
  2. Disable this pylint check for tests?
  3. Better suggestion?
like image 503
oglop Avatar asked Sep 07 '17 06:09

oglop


2 Answers

The pytest docs for @pytest.fixture say this:

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>').

So this solution is similar to your option 1, except that the pytest author suggests a slightly more descriptive name for the fixture function. So replace these two lines

@pytest.fixture def my_wallet(): 

with:

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

The description in the docs also hints at another solution which is to move the fixtures into conftest.py so they are not in the same module as the test code using the fixtures. This location is also useful for sharing fixtures among test modules.

like image 89
hallidave Avatar answered Sep 18 '22 04:09

hallidave


I just disabled that rule in my test files:

# 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 
like image 26
Garrett Bates Avatar answered Sep 17 '22 04:09

Garrett Bates