diff --git a/py/doc/test.txt b/py/doc/test.txt index 3940d317e..1a750fe48 100644 --- a/py/doc/test.txt +++ b/py/doc/test.txt @@ -136,6 +136,13 @@ Note that ``test_generative()`` will cause three tests to get run, notably ``check(42)``, ``check(17)`` and ``check(49)`` of which the middle one will obviously fail. +To make it easier to distinguish the generated tests it is possible to specify an explicit name for them, like for example:: + + def test_generative(): + for x in (42,17,49): + yield "case %d" % x, check, x + + .. _`selection by keyword`: selecting tests by keyword diff --git a/py/test/pycollect.py b/py/test/pycollect.py index ce09b4df5..db5bb4702 100644 --- a/py/test/pycollect.py +++ b/py/test/pycollect.py @@ -268,19 +268,27 @@ class Generator(FunctionMixin, PyCollectorMixin, py.test.collect.Collector): self._setupstate.prepare(self) l = [] for i, x in py.builtin.enumerate(self.obj()): - call, args = self.getcallargs(x) + name, call, args = self.getcallargs(x) if not callable(call): raise TypeError("%r yielded non callable test %r" %(self.obj, call,)) - name = "[%d]" % i + if name is None: + name = "[%d]" % i + else: + name = "['%s']" % name l.append(self.Function(name, self, args=args, callobj=call)) return l def getcallargs(self, obj): - if isinstance(obj, (tuple, list)): - call, args = obj[0], obj[1:] + if not isinstance(obj, (tuple, list)): + obj = (obj,) + # explict naming + if isinstance(obj[0], basestring): + name = obj[0] + obj = obj[1:] else: - call, args = obj, () - return call, args + name = None + call, args = obj[0], obj[1:] + return name, call, args # # Test Items diff --git a/py/test/testing/test_collect.py b/py/test/testing/test_collect.py index f9b8757af..df8d9fd04 100644 --- a/py/test/testing/test_collect.py +++ b/py/test/testing/test_collect.py @@ -152,6 +152,48 @@ class TestCollect(suptest.InlineCollection): assert gencolitems[0].name == '[0]' assert gencolitems[0].obj.func_name == 'func1' + def test_generative_functions_with_explicit_names(self): + modcol = self.getmodulecol(""" + def func1(arg, arg2): + assert arg == arg2 + + def test_gen(): + yield "one", func1, 17, 3*5 + yield "two", func1, 42, 6*7 + """) + colitems = modcol.collect() + assert len(colitems) == 1 + gencol = colitems[0] + assert isinstance(gencol, py.test.collect.Generator) + gencolitems = gencol.collect() + assert len(gencolitems) == 2 + assert isinstance(gencolitems[0], py.test.collect.Function) + assert isinstance(gencolitems[1], py.test.collect.Function) + assert gencolitems[0].name == "['one']" + assert gencolitems[0].obj.func_name == 'func1' + assert gencolitems[1].name == "['two']" + assert gencolitems[1].obj.func_name == 'func1' + + def test_generative_methods_with_explicit_names(self): + modcol = self.getmodulecol(""" + def func1(arg, arg2): + assert arg == arg2 + class TestGenMethods: + def test_gen(self): + yield "m1", func1, 17, 3*5 + yield "m2", func1, 42, 6*7 + """) + gencol = modcol.collect()[0].collect()[0].collect()[0] + assert isinstance(gencol, py.test.collect.Generator) + gencolitems = gencol.collect() + assert len(gencolitems) == 2 + assert isinstance(gencolitems[0], py.test.collect.Function) + assert isinstance(gencolitems[1], py.test.collect.Function) + assert gencolitems[0].name == "['m1']" + assert gencolitems[0].obj.func_name == 'func1' + assert gencolitems[1].name == "['m2']" + assert gencolitems[1].obj.func_name == 'func1' + def test_module_assertion_setup(self): modcol = self.getmodulecol("pass") from py.__.magic import assertion