pytest-dev / pytest

The pytest framework makes it easy to write small tests, yet scales to support complex functional testing
https://pytest.org
MIT License
11.96k stars 2.66k forks source link

Scope of parameterized fixture doesn't work #12086

Open gjambaisivanandham opened 7 months ago

gjambaisivanandham commented 7 months ago

I am fairly new to pytest and I see that scope of a parameterized fixture is not working.

Here is an example of the fixture and the test:

@pytest.fixture(scope='session')
def my_fixture(request):
       # make some API calls
       # print API call response
       return response

Tests

@pytest.mark.parametrize('my_fixture',['a','b']):
def test_scenario_1(my_fixture):
      assert response['text'] == 'abc' 

@pytest.mark.parametrize('my_fixture',['a','b']):
def test_scenario_2(my_fixture):
      assert response['image'] == 'def' 

When I run the tests I see the API responses printed 4 times(twice for a parameter and twice for b parameter). I was expecting it to be printed just twice(once for both the parameters - a and b) since both the tests use same set of parameters and the fixed is scoped session. Obviously, if I don't parameterize the fixture the api response is printed once. Pytest version is 7.4.2

RonnyPfannschmidt commented 7 months ago

I believe there was a fix for this in the 8 series

We should warn better about implicit indirect parameters having different scopes

gjambaisivanandham commented 7 months ago

I believe there was a fix for this in the 8 series

We should warn better about implicit indirect parameters having different scopes

I just tried with the latest version 8.0.2 and the issue exists in it.

WarrenTheRabbit commented 6 months ago

Thank you for posting, @gjambaisivanandham. I'm new to pytest as well so I am interested in exploring and understanding your issue.

These may be silly remarks coming from my ignorance of session scope but:

Is this the fixture usage your are expecting from file.py below. Note that test_scenario_1 uses indirect=True in my example.

import pytest

@pytest.fixture(scope='session')
def my_fixture(request):
    """I am being used."""
    pass

@pytest.mark.parametrize('my_fixture', ['a','b'], indirect=True)
def test_scenario_1(my_fixture):
    pass

@pytest.mark.parametrize('my_fixture', ['a','b'])
def test_scenario_2(my_fixture):
    pass

Fixture usage:

$ pytest file.py --fixtures-per-test
-------------------------- fixtures used by test_scenario_1[a] ---------------------------
-------------------------------------- (file.py:10) --------------------------------------
my_fixture -- file.py:4
    I am being used.

-------------------------- fixtures used by test_scenario_1[b] ---------------------------
-------------------------------------- (file.py:10) --------------------------------------
my_fixture -- file.py:4
    I am being used.

-------------------------- fixtures used by test_scenario_2[a] ---------------------------
-------------------------------------- (file.py:14) --------------------------------------
my_fixture -- src/_pytest/python.py:1113
    no docstring available

-------------------------- fixtures used by test_scenario_2[b] ---------------------------
-------------------------------------- (file.py:14) --------------------------------------
my_fixture -- src/_pytest/python.py:1113
    no docstring available