Skip to content

Fixture parametrization overwrite each other. #4948

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

Closed
4 tasks done
lexa opened this issue Mar 18, 2019 · 3 comments
Closed
4 tasks done

Fixture parametrization overwrite each other. #4948

lexa opened this issue Mar 18, 2019 · 3 comments
Labels
topic: fixtures anything involving fixtures directly or indirectly topic: parametrize related to @pytest.mark.parametrize

Comments

@lexa
Copy link

lexa commented Mar 18, 2019

  • Include a detailed description of the bug or suggestion

I'm trying to parametrize a fixture using pytest_generate_tests(), with one
caveat: parametrization is different for each test function and depends on the
function name. I want a fixture to have a different value for different
test-cases.

When metafunc.parametrize('fixture_name', ...) is called with different
arguments, it somehow overwrites global parametrization for 'fixture_name', not
a per test-function parametrization.

  • pip list of the virtual environment you are using
Package                       Version               
----------------------------- ----------------------
appdirs                       1.4.3                 
apturl                        0.5.2                 
asn1crypto                    0.24.0                
atomicwrites                  1.3.0                 
attrs                         18.2.0                
autobahn                      19.2.1                
Automat                       0.7.0                 
backports.ssl                 0.0.9                 
beautifulsoup4                4.4.1                 
blinker                       1.3                   
Brlapi                        0.6.4                 
buildbot                      2.0.1                 
buildbot-console-view         2.0.1                 
buildbot-grid-view            2.0.1                 
buildbot-waterfall-view       2.0.1                 
buildbot-worker               2.0.1                 
buildbot-www                  2.0.1                 
cffi                          1.11.2                
chardet                       2.3.0                 
checkbox-support              0.22                  
chrome-gnome-shell            0.0.0                 
click                         6.7                   
colorama                      0.3.9                 
command-not-found             0.3                   
constantly                    15.1.0                
cryptography                  2.1.4                 
decorator                     4.0.6                 
defer                         1.0.6                 
feedparser                    5.1.3                 
future                        0.17.1                
guacamole                     0.9.2                 
html5lib                      0.999                 
httplib2                      0.9.1                 
hyperlink                     18.0.0                
idna                          2.6                   
ifaddr                        0.1.6                 
IMAPClient                    1.1.0                 
incremental                   17.5.0                
ipython                       2.4.1                 
Jinja2                        2.8                   
junitxml                      0.6                   
language-selector             0.1                   
libtmux                       0.7.7                 
louis                         2.6.4                 
lxml                          3.5.0                 
mailsync                      1.0                   
Mako                          1.0.3                 
MarkupSafe                    0.23                  
more-itertools                6.0.0                 
oauthlib                      1.0.3                 
onboard                       1.2.0                 
padme                         1.1.1                 
pathlib2                      2.3.3                 
pbr                           5.1.2                 
pexpect                       4.0.1                 
Pillow                        3.1.2                 
pip                           19.0.3                
plainbox                      0.25                  
pluggy                        0.9.0                 
ply                           3.11                  
ptyprocess                    0.5                   
py                            1.8.0                 
pyasn1                        0.1.9                 
pyasn1-modules                0.2.4                 
pycparser                     2.18                  
pycups                        1.9.73                
pycurl                        7.43.0                
pygobject                     3.20.0                
PyHamcrest                    1.9.0                 
PyJWT                         1.3.0                 
pyOpenSSL                     17.5.0                
pyparsing                     2.0.3                 
pytest                        4.3.1                 
python-apt                    1.1.0b1+ubuntu0.16.4.2
python-dateutil               2.8.0                 
python-debian                 0.1.27                
python-systemd                231                   
pyxdg                         0.25                  
PyYAML                        3.12                  
reportlab                     3.3.0                 
requests                      2.9.1                 
service-identity              18.1.0                
sessioninstaller              0.0.0                 
setuptools                    20.7.0                
simplegeneric                 0.8.1                 
six                           1.11.0                
SQLAlchemy                    1.2.18                
sqlalchemy-migrate            0.12.0                
sqlparse                      0.2.4                 
ssh-import-id                 5.5                   
system-service                0.3                   
Tempita                       0.5.2                 
thriftpy                      0.3.9                 
Twisted                       18.9.0                
txaio                         18.8.1                
ubuntu-drivers-common         0.0.0                 
ufw                           0.35                  
unattended-upgrades           0.1                   
unity-scope-calculator        0.1                   
unity-scope-chromiumbookmarks 0.1                   
unity-scope-colourlovers      0.1                   
unity-scope-devhelp           0.1                   
unity-scope-firefoxbookmarks  0.1                   
unity-scope-gdrive            0.7                   
unity-scope-manpages          0.1                   
unity-scope-openclipart       0.1                   
unity-scope-texdoc            0.1                   
unity-scope-tomboy            0.1                   
unity-scope-virtualbox        0.1                   
unity-scope-yelp              0.1                   
unity-scope-zotero            0.1                   
urllib3                       1.13.1                
usb-creator                   0.3.0                 
vboxapi                       1.0                   
wheel                         0.29.0                
xdiagnose                     3.8.4.1               
xkit                          0.0.0                 
XlsxWriter                    0.7.3                 
zeroconf                      0.21.3                
zope.interface                4.6.0               
  • pytest and operating system versions
    $ pytest --version
    This is pytest version 4.3.1

    $ lsb_release -a
    No LSB modules are available.
    Distributor ID: Ubuntu
    Description: Ubuntu 16.04.6 LTS
    Release: 16.04
    Codename: xenial
    `

  • Minimal example if possible

test.py:

    def test_one(heavy_fixture):
        assert heavy_fixture == 'A'
    
    def test_two(heavy_fixture):
        assert heavy_fixture == 'B'
conftest.py:

    import pytest
    
    def pytest_generate_tests(metafunc):
        if metafunc.function.__name__ == 'test_one':
            params = ['A']
        else:
            params = ['B']
    
        metafunc.parametrize('heavy_fixture', params, scope="session", indirect=True)
    
    @pytest.fixture
    def heavy_fixture(request):
        # Do a lot of heavy computation here
        return request.param

results:

    $ pytest  test.py  
    ============================================================================ test session starts =============================================================================
    platform linux -- Python 3.5.2, pytest-4.3.1, py-1.8.0, pluggy-0.9.0
    rootdir: /home/afe/pytest3_fail, inifile:
    collected 2 items                                                                                                                                                            
    
    test.py .F                                                                                                                                                             [100%]
    
    ================================================================================== FAILURES ==================================================================================
    ________________________________________________________________________________ test_two[B] _________________________________________________________________________________
    
    heavy_fixture = 'A'
    
        def test_two(heavy_fixture):
    >       assert heavy_fixture == 'B'
    E       AssertionError: assert 'A' == 'B'
    E         - A
    E         + B
    
    test.py:5: AssertionError
    ===================================================================== 1 failed, 1 passed in 0.02 seconds =====================================================================

@lexa lexa changed the title Fixtu Fixture parametrization overwrite each other. Mar 18, 2019
@HunterMcGushion
Copy link

Hi, I may be misunderstanding what you're saying here

When metafunc.parametrize('fixture_name', ...) is called with different
arguments, it somehow overwrites global parametrization for 'fixture_name', not
a per test-function parametrization.

However, is there a reason you can't use scope="function" in the conftest.pytest_generate_tests function's call to metafunc.parameterize?

Here's the updated conftest.py, which makes your tests pass:

def pytest_generate_tests(metafunc):
    if metafunc.function.__name__ == 'test_one':
        params = ['A']
    else:
        params = ['B']

    # Below line was changed
    metafunc.parametrize('heavy_fixture', params, scope="function", indirect=True)


@pytest.fixture
def heavy_fixture(request):
    # Do a lot of heavy computation here
    return request.param

@lexa
Copy link
Author

lexa commented Mar 20, 2019

However, is there a reason you can't use scope="function" in the conftest.pytest_generate_tests function's call to metafunc.parameterize?

The reason to use score="session" is that the fixture is very computationally heavy and I want to minimize the number of times it is called.

in the example below the fixture is called 4 times, while it is enough to call it only twice with scope="session"

def pytest_generate_tests(metafunc):
    params = ['A', 'B']
    metafunc.parametrize('heavy_fixture', params, scope="function", indirect=True)

@Zac-HD Zac-HD added topic: fixtures anything involving fixtures directly or indirectly topic: parametrize related to @pytest.mark.parametrize labels Apr 6, 2019
@bluetech
Copy link
Member

This has been fixed by @aklajnert in #5798 (pytest 5.1.2).

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

No branches or pull requests

4 participants