From be1954afbcec9f9470a0a9dfbfe09f025ce78ddf Mon Sep 17 00:00:00 2001 From: palaviv Date: Sat, 19 Mar 2016 21:22:49 +0200 Subject: [PATCH 1/6] allow None to be passed in ids list for specific test and recieve idmaker name for test --- _pytest/python.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/_pytest/python.py b/_pytest/python.py index 3580eae074f..d7ce0e8ee84 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1017,8 +1017,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): @@ -1130,13 +1129,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 From a8cfd54871640bf4bcceafc9ae82ffaa33feda48 Mon Sep 17 00:00:00 2001 From: palaviv Date: Sat, 19 Mar 2016 21:23:49 +0200 Subject: [PATCH 2/6] added test for None in idmaker --- testing/python/metafunc.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index faa687f4056..75bd350c3fe 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -258,6 +258,13 @@ 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_addcall_and_parametrize(self): def func(x, y): pass metafunc = self.Metafunc(func) From 877ca5a0bf50bd9406d7cea3f7b4d595071d7bd1 Mon Sep 17 00:00:00 2001 From: palaviv Date: Sat, 19 Mar 2016 21:38:24 +0200 Subject: [PATCH 3/6] added test for None in paramtrized ids list --- testing/python/metafunc.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 75bd350c3fe..0b719d183a2 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -796,6 +796,24 @@ 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", + ]) + @pytest.mark.parametrize(("scope", "length"), [("module", 2), ("function", 4)]) def test_parametrize_scope_overrides(self, testdir, scope, length): From 4b0237c8ee6ff511109e3f9237d2e08a4c3089c0 Mon Sep 17 00:00:00 2001 From: palaviv Date: Sat, 19 Mar 2016 21:42:47 +0200 Subject: [PATCH 4/6] added test for unique names when recievieng identical ids in parametrize --- testing/python/metafunc.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 0b719d183a2..f0f3dbd4cbd 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -265,6 +265,13 @@ def test_idmaker_with_ids(self): 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) @@ -800,7 +807,7 @@ 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)], + metafunc.parametrize(("a", "b"), [(1,1), (1,1), (1,2)], ids=["basic", None, "advanced"]) def test_function(a, b): @@ -814,6 +821,23 @@ def test_function(a, b): "*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): From 32f44ce2fd5c8df5e96907b590599b5a140f59b5 Mon Sep 17 00:00:00 2001 From: palaviv Date: Sun, 20 Mar 2016 18:54:48 +0200 Subject: [PATCH 5/6] updated parametrize documentation --- _pytest/python.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_pytest/python.py b/_pytest/python.py index d7ce0e8ee84..5fe41cb676a 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -956,7 +956,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. From dd384f7f78431866ee6ecbf55440472b4a27fd5f Mon Sep 17 00:00:00 2001 From: palaviv Date: Sun, 20 Mar 2016 19:01:47 +0200 Subject: [PATCH 6/6] Added changlog entries --- CHANGELOG.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0a492c6b4a9..159b3fae2c9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -23,7 +23,8 @@ **Changes** -* +* parametrize ids can accept None as specific test id. The + automatically generated id for that argument will be used. * @@ -45,7 +46,7 @@ **Bug Fixes** -* +* When receiving identical test ids in parametrize we generate unique test ids. *