A couple of improvements to parametrize

- When not specifying ids, let None and bools use their native string form (like str, int, float) rather than obfuscated form used for objects
- When specifying ids, explicitly raise a ValueError if a different number of ids are specified compared to the test cases
- Add tests for both these items.
This commit is contained in:
Brianna Laugher 2013-05-29 12:59:47 +10:00
parent c294a417bd
commit 345b8391c4
2 changed files with 35 additions and 3 deletions

View File

@ -2,6 +2,7 @@
import py import py
import inspect import inspect
import sys import sys
from types import NoneType
import pytest import pytest
from _pytest.main import getfslineno from _pytest.main import getfslineno
from _pytest.mark import MarkDecorator, MarkInfo from _pytest.mark import MarkDecorator, MarkInfo
@ -705,6 +706,9 @@ class Metafunc(FuncargnamesCompatAttr):
raise ValueError("%r uses no fixture %r" %( raise ValueError("%r uses no fixture %r" %(
self.function, arg)) self.function, arg))
valtype = indirect and "params" or "funcargs" valtype = indirect and "params" or "funcargs"
if ids and len(ids) != len(argvalues):
raise ValueError('%d tests specified with %d ids' %(
len(argvalues), len(ids)))
if not ids: if not ids:
ids = idmaker(argnames, argvalues) ids = idmaker(argnames, argvalues)
newcalls = [] newcalls = []
@ -758,7 +762,7 @@ def idmaker(argnames, argvalues):
for valindex, valset in enumerate(argvalues): for valindex, valset in enumerate(argvalues):
this_id = [] this_id = []
for nameindex, val in enumerate(valset): for nameindex, val in enumerate(valset):
if not isinstance(val, (float, int, str)): if not isinstance(val, (float, int, str, bool, NoneType)):
this_id.append(str(argnames[nameindex])+str(valindex)) this_id.append(str(argnames[nameindex])+str(valindex))
else: else:
this_id.append(str(val)) this_id.append(str(val))

View File

@ -95,6 +95,17 @@ class TestMetafunc:
ids = [x.id for x in metafunc._calls] ids = [x.id for x in metafunc._calls]
assert ids == ["basic-abc", "basic-def", "advanced-abc", "advanced-def"] assert ids == ["basic-abc", "basic-def", "advanced-abc", "advanced-def"]
def test_parametrize_with_wrong_number_of_ids(self, testdir):
def func(x, y): pass
metafunc = self.Metafunc(func)
with pytest.raises(ValueError):
metafunc.parametrize("x", [1,2], ids=['basic'])
with pytest.raises(ValueError):
metafunc.parametrize(("x","y"), [("abc", "def"),
("ghi", "jkl")], ids=["one"])
def test_parametrize_with_userobjects(self): def test_parametrize_with_userobjects(self):
def func(x, y): pass def func(x, y): pass
metafunc = self.Metafunc(func) metafunc = self.Metafunc(func)
@ -121,6 +132,25 @@ class TestMetafunc:
result = idmaker((py.builtin._totext("a"), "b"), [({}, '\xc3\xb4')]) result = idmaker((py.builtin._totext("a"), "b"), [({}, '\xc3\xb4')])
assert result == ['a0-\xc3\xb4'] assert result == ['a0-\xc3\xb4']
def test_idmaker_native_strings(self):
from _pytest.python import idmaker
result = idmaker(("a", "b"), [(1.0, -1.1),
(2, -202),
("three", "three hundred"),
(True, False),
(None, None),
(list("six"), [66, 66]),
({7}, set("seven")),
(tuple("eight"), (8, -8, 8))
])
assert result == ["1.0--1.1",
"2--202",
"three-three hundred",
"True-False",
"None-None",
"a5-b5",
"a6-b6",
"a7-b7"]
def test_addcall_and_parametrize(self): def test_addcall_and_parametrize(self):
def func(x, y): pass def func(x, y): pass
@ -530,8 +560,6 @@ class TestMetafuncFunctional:
*test_function*1.3-b1* *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):