This rule raises an issue when the argvalues collection of a @pytest.mark.parametrize decorator contains duplicate test
cases.
In Python with pytest, this occurs when @pytest.mark.parametrize is given an argvalues sequence that repeats the same
case more than once (for example duplicate literals, names, or calls).
@pytest.mark.parametrize runs the decorated test once for each entry in its values collection. Duplicate cases therefore execute the
same scenario more than once.
That wastes CI time and usually signals a copy-paste mistake: an intended distinct case was never updated, so coverage looks broader than it is.
Duplicates are detected by comparing the parametrize entries as expressions (literals, names, calls, and other AST forms), not only literal values. Accidental duplicates should be removed. Rarely, repeated identical entries are intentional when each run exercises mutable shared state; keep those only when that is deliberate.
This rule complements {rule:python:S8998}, which flags empty parametrize value lists.
Duplicate cases inflate suite runtime and can hide unfinished copy-paste edits. Teams may believe a scenario is covered in several ways when the same inputs are simply repeated.
When the duplicate is accidental, remove the repeated entries from the @pytest.mark.parametrize values list so each case appears only
once. If the repeated entry was meant to be a different scenario, replace it with the intended distinct inputs.
Do not remove duplicates that are intentional for stateful behavior (for example repeated invocations that observe mutable global state). In those cases, keep the repeated cases or make the shared-state dependency explicit another way.
import pytest
@pytest.mark.parametrize("n", [1, 2, 2, 3]) # Noncompliant
def test_double(n):
assert double(n) == n * 2
import pytest
@pytest.mark.parametrize("n", [1, 2, 3])
def test_double(n):
assert double(n) == n * 2
import pytest
@pytest.mark.parametrize("operand,expected", [
(1, 2),
(2, 4),
(1, 2), # Noncompliant
(3, 6),
])
def test_double(operand, expected):
assert double(operand) == expected
import pytest
@pytest.mark.parametrize("operand,expected", [
(1, 2),
(2, 4),
(3, 6),
])
def test_double(operand, expected):
assert double(operand) == expected