set pytest fixture's scope dynamically from args

Viewed 235

A little background:

  • In fixture, I am configuring a browser and closing it in teardown part.
  • The scope of the fixture can be dynamic due to the integration with Saucelabs.
  • The reason behind is the timeout of a browser configured in SauceLabs.
  • That means if I have too many test cases, I have to provide scope="function", otherwise "class" would work.

I want to configure the scope of the fixture dynamically, how can I achieve it.?

Is it possible to configure a pytest args like "--scope={scope}" and provide it to fixture.?

Pseudo code snippet:

@pytest.fixture(scope="function")
def test_helper(request):
    # Configure browser

    browser = # Saucelab browser
    yield browser
    browser.quit()
1 Answers

you can create an option for your fixture to consume and tell pytest to make it dynamic using kwarg scope=callable

https://docs.pytest.org/en/6.2.x/fixture.html#dynamic-scope

def pytest_addoption(parser):
    parser.addoption('--precious', default=None, help='cli to set scope of fixture "precious"')

def myscope(fixture_name, config):
    scope = config.getoption(fixture_name) or 'function'
    return scope

ring_count = Counter()

@fixture(scope=myscope)
def one_ring(request):
    response = Object()
    yield response 
    ring_count[id(response)] += 1
    # do something here to assert about the id of precious
    if request.config.option.precious:
        assert len(ring_count) == 1

def test_lord(precious):
    """a test about dynamic scope."""

def test_owner(precious):
    """if --precious, then precious is the one ring that all tests get."""
Related