improve automatic id generation for parametrized tests

This commit is contained in:
holger krekel 2012-10-19 10:07:13 +02:00
parent 024df6e00b
commit b0b6695538
5 changed files with 65 additions and 38 deletions

View File

@ -1,6 +1,7 @@
Changes between 2.2.4 and 2.3.0.dev Changes between 2.2.4 and 2.3.0.dev
----------------------------------- -----------------------------------
- fix issue202 - better automatic names for parametrized test functions
- fix issue139 - introduce @pytest.fixture which allows direct scoping - fix issue139 - introduce @pytest.fixture which allows direct scoping
and parametrization of funcarg factories. Introduce new @pytest.setup and parametrization of funcarg factories. Introduce new @pytest.setup
marker to allow the writing of setup functions which accept funcargs. marker to allow the writing of setup functions which accept funcargs.

View File

@ -1,2 +1,2 @@
# #
__version__ = '2.3.0.dev31' __version__ = '2.3.0.dev32'

View File

@ -660,8 +660,7 @@ class Metafunc(FuncargnamesCompatAttr):
self.function, arg)) self.function, arg))
valtype = indirect and "params" or "funcargs" valtype = indirect and "params" or "funcargs"
if not ids: if not ids:
idmaker = IDMaker() ids = idmaker(argnames, argvalues)
ids = list(map(idmaker, argvalues))
newcalls = [] newcalls = []
for callspec in self._calls or [CallSpec2(self)]: for callspec in self._calls or [CallSpec2(self)]:
for i, valset in enumerate(argvalues): for i, valset in enumerate(argvalues):
@ -708,18 +707,17 @@ class Metafunc(FuncargnamesCompatAttr):
cs.setall(funcargs, id, param) cs.setall(funcargs, id, param)
self._calls.append(cs) self._calls.append(cs)
class IDMaker: def idmaker(argnames, argvalues):
def __init__(self): idlist = []
self.counter = 0 for valindex, valset in enumerate(argvalues):
def __call__(self, valset): this_id = []
l = [] for nameindex, val in enumerate(valset):
for val in valset: if not isinstance(val, (float, int, str)):
if not isinstance(val, (int, str)): this_id.append(argnames[nameindex]+str(valindex))
val = "."+str(self.counter) else:
self.counter += 1 this_id.append(str(val))
l.append(str(val)) idlist.append("-".join(this_id))
return "-".join(l) return idlist
def showfixtures(config): def showfixtures(config):
from _pytest.main import wrap_session from _pytest.main import wrap_session

View File

@ -24,7 +24,7 @@ def main():
name='pytest', name='pytest',
description='py.test: simple powerful testing with Python', description='py.test: simple powerful testing with Python',
long_description = long_description, long_description = long_description,
version='2.3.0.dev31', version='2.3.0.dev32',
url='http://pytest.org', url='http://pytest.org',
license='MIT license', license='MIT license',
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],

View File

@ -992,10 +992,21 @@ class TestMetafunc:
pass pass
metafunc.parametrize("x", [A(), A()]) metafunc.parametrize("x", [A(), A()])
metafunc.parametrize("y", list("ab")) metafunc.parametrize("y", list("ab"))
assert metafunc._calls[0].id == ".0-a" assert metafunc._calls[0].id == "x0-a"
assert metafunc._calls[1].id == ".0-b" assert metafunc._calls[1].id == "x0-b"
assert metafunc._calls[2].id == ".1-a" assert metafunc._calls[2].id == "x1-a"
assert metafunc._calls[3].id == ".1-b" assert metafunc._calls[3].id == "x1-b"
def test_idmaker_autoname(self):
from _pytest.python import idmaker
result = idmaker(("a", "b"), [("string", 1.0),
("st-ring", 2.0)])
assert result == ["string-1.0", "st-ring-2.0"]
result = idmaker(("a", "b"), [(object(), 1.0),
(object(), object())])
assert result == ["a0-1.0", "a1-b1"]
def test_addcall_and_parametrize(self): def test_addcall_and_parametrize(self):
def func(x, y): pass def func(x, y): pass
@ -1362,6 +1373,41 @@ class TestMetafuncFunctional:
"*1 passed*" "*1 passed*"
]) ])
def test_parametrize_with_ids(self, testdir):
testdir.makepyfile("""
import pytest
def pytest_generate_tests(metafunc):
metafunc.parametrize(("a", "b"), [(1,1), (1,2)],
ids=["basic", "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*advanced*FAILED",
])
def test_parametrize_without_ids(self, testdir):
testdir.makepyfile("""
import pytest
def pytest_generate_tests(metafunc):
metafunc.parametrize(("a", "b"),
[(1,object()), (1.3,object())])
def test_function(a, b):
assert 1
""")
result = testdir.runpytest("-v")
result.stdout.fnmatch_lines("""
*test_function*1-b0*
*test_function*1.3-b1*
""")
@pytest.mark.parametrize(("scope", "length"), @pytest.mark.parametrize(("scope", "length"),
[("module", 2), ("function", 4)]) [("module", 2), ("function", 4)])
def test_parametrize_scope_overrides(self, testdir, scope, length): def test_parametrize_scope_overrides(self, testdir, scope, length):
@ -1985,24 +2031,6 @@ class TestFixtureUsages:
reprec = testdir.inline_run() reprec = testdir.inline_run()
reprec.assertoutcome(passed=2) reprec.assertoutcome(passed=2)
class TestResourceIntegrationFunctional:
def test_parametrize_with_ids(self, testdir):
testdir.makepyfile("""
import pytest
def pytest_generate_tests(metafunc):
metafunc.parametrize(("a", "b"), [(1,1), (1,2)],
ids=["basic", "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*advanced*FAILED",
])
class TestFixtureManager: class TestFixtureManager:
def pytest_funcarg__testdir(self, request): def pytest_funcarg__testdir(self, request):
testdir = request.getfuncargvalue("testdir") testdir = request.getfuncargvalue("testdir")