Skip to content

I want a rule that will advise replacing pytest.mark.parametrize calls using the ids keyword argument with pytest.params(.., id=...) parameter sets.  #328

@UnknownPlatypus

Description

@UnknownPlatypus

Rule request

Description

The plugin should check for pytest.mark.parametrize calls using the ids keyword argument and advise replacing each set of test values with a pytest.params(.., id=...) parameter set, effectively binding the id with the set of arguments.

Rationale

When using the ids=[…] syntax, each id is bound to a set of parameters by index. This is quite error prone and makes test hard to modify (adding a test case in the middle means adding an id at the corresponding index in the ids list). Moreover, if one test case fails, it's not directly obvious which set of parameters is associated with the failing id. This issue gets worse the more test case you have in your parametrize call.

Pytest documentation seems to agree this is not a good pattern:

In test_timedistance_v1, we specified ids as a list of strings which were used as the test IDs. These are succinct, but can be a pain to maintain.

Examples:

Bad code:

@pytest.mark.parametrize(
    "a, b, expected",
    [
        (datetime(2001, 12, 12), datetime(2001, 12, 11), timedelta(1)),
        ... # 10 other test cases
        (datetime(2001, 12, 11), datetime(2001, 12, 12), timedelta(-1)),
    ],
    ids=["forward", ..., "backward"],
)
def test(a, b, expected):
    pass

Good code:

@pytest.mark.parametrize(
    "a, b, expected",
    [
        pytest.param(
            datetime(2001, 12, 12), datetime(2001, 12, 11), timedelta(1), id="forward"
        ),
        ... # 10 other test cases
        pytest.param(
            datetime(2001, 12, 11), datetime(2001, 12, 12), timedelta(-1), id="backward"
        ),
    ],
)
def test(a, b, expected):
    pass

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions