Skip to content

Commit da10451

Browse files
Merge pull request #1468 from palaviv/allow-none-as-parametrized-test-id
None in paramtrized test id will use automatically generated id
2 parents 2cfcf12 + dd384f7 commit da10451

File tree

3 files changed

+64
-11
lines changed

3 files changed

+64
-11
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323

2424
**Changes**
2525

26-
*
26+
* parametrize ids can accept None as specific test id. The
27+
automatically generated id for that argument will be used.
2728

2829
*
2930

@@ -45,7 +46,7 @@
4546

4647
**Bug Fixes**
4748

48-
*
49+
* When receiving identical test ids in parametrize we generate unique test ids.
4950

5051
*
5152

_pytest/python.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,8 @@ def parametrize(self, argnames, argvalues, indirect=False, ids=None,
967967
968968
:arg ids: list of string ids, or a callable.
969969
If strings, each is corresponding to the argvalues so that they are
970-
part of the test id.
970+
part of the test id. If None is given as id of specific test, the
971+
automatically generated id for that argument will be used.
971972
If callable, it should take one argument (a single argvalue) and return
972973
a string or return None. If None, the automatically generated id for that
973974
argument will be used.
@@ -1028,8 +1029,7 @@ def parametrize(self, argnames, argvalues, indirect=False, ids=None,
10281029
if ids and len(ids) != len(argvalues):
10291030
raise ValueError('%d tests specified with %d ids' %(
10301031
len(argvalues), len(ids)))
1031-
if not ids:
1032-
ids = idmaker(argnames, argvalues, idfn)
1032+
ids = idmaker(argnames, argvalues, idfn, ids)
10331033
newcalls = []
10341034
for callspec in self._calls or [CallSpec2(self)]:
10351035
for param_index, valset in enumerate(argvalues):
@@ -1141,13 +1141,16 @@ def _idval(val, argname, idx, idfn):
11411141
pass
11421142
return str(argname)+str(idx)
11431143

1144-
def _idvalset(idx, valset, argnames, idfn):
1145-
this_id = [_idval(val, argname, idx, idfn)
1146-
for val, argname in zip(valset, argnames)]
1147-
return "-".join(this_id)
1144+
def _idvalset(idx, valset, argnames, idfn, ids):
1145+
if ids is None or ids[idx] is None:
1146+
this_id = [_idval(val, argname, idx, idfn)
1147+
for val, argname in zip(valset, argnames)]
1148+
return "-".join(this_id)
1149+
else:
1150+
return ids[idx]
11481151

1149-
def idmaker(argnames, argvalues, idfn=None):
1150-
ids = [_idvalset(valindex, valset, argnames, idfn)
1152+
def idmaker(argnames, argvalues, idfn=None, ids=None):
1153+
ids = [_idvalset(valindex, valset, argnames, idfn, ids)
11511154
for valindex, valset in enumerate(argvalues)]
11521155
if len(set(ids)) < len(ids):
11531156
# user may have provided a bad idfn which means the ids are not unique

testing/python/metafunc.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,20 @@ def ids(val):
258258
"three-b2",
259259
]
260260

261+
def test_idmaker_with_ids(self):
262+
from _pytest.python import idmaker
263+
result = idmaker(("a", "b"), [(1, 2),
264+
(3, 4)],
265+
ids=["a", None])
266+
assert result == ["a", "3-4"]
267+
268+
def test_idmaker_with_ids_unique_names(self):
269+
from _pytest.python import idmaker
270+
result = idmaker(("a", "b"), [(1, 2),
271+
(3, 4)],
272+
ids=["a", "a"])
273+
assert result == ["0a", "1a"]
274+
261275
def test_addcall_and_parametrize(self):
262276
def func(x, y): pass
263277
metafunc = self.Metafunc(func)
@@ -789,6 +803,41 @@ def test_function(a, b):
789803
*test_function*1.3-b1*
790804
""")
791805

806+
def test_parametrize_with_None_in_ids(self, testdir):
807+
testdir.makepyfile("""
808+
import pytest
809+
def pytest_generate_tests(metafunc):
810+
metafunc.parametrize(("a", "b"), [(1,1), (1,1), (1,2)],
811+
ids=["basic", None, "advanced"])
812+
813+
def test_function(a, b):
814+
assert a == b
815+
""")
816+
result = testdir.runpytest("-v")
817+
assert result.ret == 1
818+
result.stdout.fnmatch_lines_random([
819+
"*test_function*basic*PASSED",
820+
"*test_function*1-1*PASSED",
821+
"*test_function*advanced*FAILED",
822+
])
823+
824+
def test_parametrize_with_identical_ids_get_unique_names(self, testdir):
825+
testdir.makepyfile("""
826+
import pytest
827+
def pytest_generate_tests(metafunc):
828+
metafunc.parametrize(("a", "b"), [(1,1), (1,2)],
829+
ids=["a", "a"])
830+
831+
def test_function(a, b):
832+
assert a == b
833+
""")
834+
result = testdir.runpytest("-v")
835+
assert result.ret == 1
836+
result.stdout.fnmatch_lines_random([
837+
"*test_function*0a*PASSED",
838+
"*test_function*1a*FAILED"
839+
])
840+
792841
@pytest.mark.parametrize(("scope", "length"),
793842
[("module", 2), ("function", 4)])
794843
def test_parametrize_scope_overrides(self, testdir, scope, length):

0 commit comments

Comments
 (0)