Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class scoped fixture is called multiple times with mutable values and parameterisation #7175

Open
JSchulte01 opened this issue May 7, 2020 · 1 comment
Labels
status: help wanted developers would like help from experts on this topic topic: fixtures anything involving fixtures directly or indirectly topic: parametrize related to @pytest.mark.parametrize

Comments

@JSchulte01
Copy link

JSchulte01 commented May 7, 2020

  • [ x] a detailed description of the bug or suggestion
  • [ x] output of pip list from the virtual environment you are using
  • [ x] pytest and operating system versions
  • [ x] minimal example if possible

When setting up test parameterisation using a combination of pytest_generate_test hooks and fixture decorators, along with pytest.mark.parameterize decorators I'm seeing inconsistent behaviour with the fixtures which have scope='class'. In the application context these fixtures load large tables of data which takes quite a long time.

When an immutable object is passed as the fixture parameter - the fixtures behave as expected, however when mutable object, like a list is passed, the class fixture gets called repeatedly. The workaround identified in #896 did not seem to make a difference so I have opened a new issue.

If this is expected behaviour or a known bug I would like to add a warning to the docs to make this clear.

Possibly Related

#3678, #896

LSB Release

Distributor ID:	Ubuntu
Description:	Ubuntu 16.04.6 LTS
Release:	16.04
Codename:	xenial

PIP Freeze >>

attrs==19.3.0
importlib-metadata==1.6.0
more-itertools==8.2.0
packaging==20.3
pluggy==0.13.1
py==1.8.1
pyparsing==2.4.7
pytest==5.4.1
six==1.14.0
wcwidth==0.1.9
zipp==3.1.0

Minimum Reproducible Example

import pytest

def pytest_generate_tests(metafunc):

    if 'fixture_a' in metafunc.fixturenames:
        metafunc.parametrize(
            'fixture_a',
            [1, ('a',), ['b']],
            scope='class',
            indirect=True,
        )


@pytest.fixture(scope='session')
def fixture_a(request):
    print('fixture_a CALLED')
    return request.param


class TestExp:

    @pytest.fixture(scope='class')
    def fixture_d(self, fixture_a):
        print('fixture_d CALLED')
        return fixture_a

    def test_func_one(self, fixture_d):
        print(fixture_d)

    @pytest.mark.parametrize(
        'param_a',
        ['*', '+']
    )
    def test_func_two(self, fixture_d, param_a):
        print(fixture_d, ' -> ', param_a)

Output of Test

platform linux -- Python 3.6.8, pytest-5.4.1, py-1.8.1, pluggy-0.13.1 -- ...
cachedir: .pytest_cache
rootdir: ...
collected 9 items                                                                                                                                                                                          

test_mre.py::TestExp::test_func_one[1] 
fixture_a CALLED
fixture_d CALLED
1
PASSED
test_mre.py::TestExp::test_func_two[1-*] 1  ->  *
PASSED
test_mre.py::TestExp::test_func_two[1-+] 1  ->  +
PASSED

test_mre.py::TestExp::test_func_one[fixture_a1] 
fixture_a CALLED
fixture_d CALLED
('a',)
PASSED
test_mre.py::TestExp::test_func_two[fixture_a1-*] ('a',)  ->  *
PASSED
test_mre.py::TestExp::test_func_two[fixture_a1-+] ('a',)  ->  +
PASSED

test_mre.py::TestExp::test_func_one[fixture_a2] 
fixture_a CALLED
fixture_d CALLED
['b']
PASSED
test_mre.py::TestExp::test_func_two[fixture_a2-*]               <<< ---- Class scoped fixture called twice
fixture_a CALLED
fixture_d CALLED
['b']  ->  *
PASSED
test_mre.py::TestExp::test_func_two[fixture_a2-+] ['b']  ->  +
PASSED
@Zac-HD Zac-HD added status: help wanted developers would like help from experts on this topic topic: fixtures anything involving fixtures directly or indirectly topic: parametrize related to @pytest.mark.parametrize labels May 10, 2020
@symonk
Copy link
Member

symonk commented May 23, 2020

smells like fixture caching / is vs == checks at a glance - will investigate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: help wanted developers would like help from experts on this topic topic: fixtures anything involving fixtures directly or indirectly topic: parametrize related to @pytest.mark.parametrize
Projects
None yet
Development

No branches or pull requests

3 participants