Skip to content

Commit

Permalink
Merge pull request #1468 from palaviv/allow-none-as-parametrized-test-id
Browse files Browse the repository at this point in the history
None in paramtrized test id will use automatically generated id
  • Loading branch information
RonnyPfannschmidt committed Mar 20, 2016
2 parents 2cfcf12 + dd384f7 commit da10451
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 11 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@

**Changes**

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

*

Expand All @@ -45,7 +46,7 @@

**Bug Fixes**

*
* When receiving identical test ids in parametrize we generate unique test ids.

*

Expand Down
21 changes: 12 additions & 9 deletions _pytest/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,8 @@ def parametrize(self, argnames, argvalues, indirect=False, ids=None,
:arg ids: list of string ids, or a callable.
If strings, each is corresponding to the argvalues so that they are
part of the test id.
part of the test id. If None is given as id of specific test, the
automatically generated id for that argument will be used.
If callable, it should take one argument (a single argvalue) and return
a string or return None. If None, the automatically generated id for that
argument will be used.
Expand Down Expand Up @@ -1028,8 +1029,7 @@ def parametrize(self, argnames, argvalues, indirect=False, ids=None,
if ids and len(ids) != len(argvalues):
raise ValueError('%d tests specified with %d ids' %(
len(argvalues), len(ids)))
if not ids:
ids = idmaker(argnames, argvalues, idfn)
ids = idmaker(argnames, argvalues, idfn, ids)
newcalls = []
for callspec in self._calls or [CallSpec2(self)]:
for param_index, valset in enumerate(argvalues):
Expand Down Expand Up @@ -1141,13 +1141,16 @@ def _idval(val, argname, idx, idfn):
pass
return str(argname)+str(idx)

def _idvalset(idx, valset, argnames, idfn):
this_id = [_idval(val, argname, idx, idfn)
for val, argname in zip(valset, argnames)]
return "-".join(this_id)
def _idvalset(idx, valset, argnames, idfn, ids):
if ids is None or ids[idx] is None:
this_id = [_idval(val, argname, idx, idfn)
for val, argname in zip(valset, argnames)]
return "-".join(this_id)
else:
return ids[idx]

def idmaker(argnames, argvalues, idfn=None):
ids = [_idvalset(valindex, valset, argnames, idfn)
def idmaker(argnames, argvalues, idfn=None, ids=None):
ids = [_idvalset(valindex, valset, argnames, idfn, ids)
for valindex, valset in enumerate(argvalues)]
if len(set(ids)) < len(ids):
# user may have provided a bad idfn which means the ids are not unique
Expand Down
49 changes: 49 additions & 0 deletions testing/python/metafunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,20 @@ def ids(val):
"three-b2",
]

def test_idmaker_with_ids(self):
from _pytest.python import idmaker
result = idmaker(("a", "b"), [(1, 2),
(3, 4)],
ids=["a", None])
assert result == ["a", "3-4"]

def test_idmaker_with_ids_unique_names(self):
from _pytest.python import idmaker
result = idmaker(("a", "b"), [(1, 2),
(3, 4)],
ids=["a", "a"])
assert result == ["0a", "1a"]

def test_addcall_and_parametrize(self):
def func(x, y): pass
metafunc = self.Metafunc(func)
Expand Down Expand Up @@ -789,6 +803,41 @@ def test_function(a, b):
*test_function*1.3-b1*
""")

def test_parametrize_with_None_in_ids(self, testdir):
testdir.makepyfile("""
import pytest
def pytest_generate_tests(metafunc):
metafunc.parametrize(("a", "b"), [(1,1), (1,1), (1,2)],
ids=["basic", None, "advanced"])
def test_function(a, b):
assert a == b
""")
result = testdir.runpytest("-v")
assert result.ret == 1
result.stdout.fnmatch_lines_random([
"*test_function*basic*PASSED",
"*test_function*1-1*PASSED",
"*test_function*advanced*FAILED",
])

def test_parametrize_with_identical_ids_get_unique_names(self, testdir):
testdir.makepyfile("""
import pytest
def pytest_generate_tests(metafunc):
metafunc.parametrize(("a", "b"), [(1,1), (1,2)],
ids=["a", "a"])
def test_function(a, b):
assert a == b
""")
result = testdir.runpytest("-v")
assert result.ret == 1
result.stdout.fnmatch_lines_random([
"*test_function*0a*PASSED",
"*test_function*1a*FAILED"
])

@pytest.mark.parametrize(("scope", "length"),
[("module", 2), ("function", 4)])
def test_parametrize_scope_overrides(self, testdir, scope, length):
Expand Down

0 comments on commit da10451

Please sign in to comment.