Add skip_on_empty option to skip tests on an empty iterable
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 1a11ddd..17cc2e3 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,6 +1,7 @@
-0.6.2 (???)
+0.6.2 (2018-03-11)
* Make sure that `setUp` and `tearDown` methods work correctly (#40)
- * Made it so that a ValueError is raised when an empty iterable is used to parameterize
+ * Raise a ValueError when input is empty (thanks @danielbradburn;
+ https://github.com/wolever/parameterized/pull/48)
0.6.1 (2017-03-21)
* Rename package from nose-parameterized to parameterized. A
diff --git a/parameterized/parameterized.py b/parameterized/parameterized.py
index ed37799..5b0a336 100644
--- a/parameterized/parameterized.py
+++ b/parameterized/parameterized.py
@@ -13,6 +13,12 @@
from unittest import TestCase
+try:
+ from unittest import SkipTest
+except ImportError:
+ class SkipTest(Exception):
+ pass
+
PY3 = sys.version_info[0] == 3
PY2 = sys.version_info[0] == 2
@@ -40,6 +46,9 @@
_param = namedtuple("param", "args kwargs")
+def skip_on_empty_helper(*a, **kw):
+ raise SkipTest("parameterized input is empty")
+
class param(_param):
""" Represents a single parameter to a test case.
@@ -282,9 +291,10 @@
assert_equal(a + b, expected)
"""
- def __init__(self, input, doc_func=None):
+ def __init__(self, input, doc_func=None, skip_on_empty=False):
self.get_input = self.input_as_callable(input)
self.doc_func = doc_func or default_doc_func
+ self.skip_on_empty = skip_on_empty
def __call__(self, test_func):
self.assert_not_in_testcase_subclass()
@@ -321,11 +331,17 @@
delattr(test_cls, test_func.__name__)
wrapper.__doc__ = original_doc
- wrapper.parameterized_input = self.get_input()
+ input = self.get_input()
+ if not input:
+ if not self.skip_on_empty:
+ raise ValueError(
+ "Parameters iterable is empty (hint: use "
+ "`parameterized([], skip_on_empty=True)` to skip "
+ "this test when the input is empty)"
+ )
+ wrapper = wraps(test_func)(lambda: skip_on_empty_helper())
- if not wrapper.parameterized_input:
- raise ValueError('Parameters iterable was empty')
-
+ wrapper.parameterized_input = input
wrapper.parameterized_func = test_func
test_func.__name__ = "_parameterized_original_%s" %(test_func.__name__, )
@@ -393,7 +409,8 @@
return [ param.from_decorator(p) for p in input_values ]
@classmethod
- def expand(cls, input, name_func=None, doc_func=None, **legacy):
+ def expand(cls, input, name_func=None, doc_func=None, skip_on_empty=False,
+ **legacy):
""" A "brute force" method of parameterizing test cases. Creates new
test cases and injects them into the namespace that the wrapped
function is being defined in. Useful for parameterizing tests in
@@ -432,7 +449,13 @@
paramters = cls.input_as_callable(input)()
if not paramters:
- raise ValueError('input was empty')
+ if not skip_on_empty:
+ raise ValueError(
+ "Parameters iterable is empty (hint: use "
+ "`parameterized.expand([], skip_on_empty=True)` to skip "
+ "this test when the input is empty)"
+ )
+ return wraps(f)(lambda: skip_on_empty_helper())
for num, p in enumerate(paramters):
name = name_func(f, num, p)
diff --git a/parameterized/test.py b/parameterized/test.py
index 9821af1..2a1f26b 100644
--- a/parameterized/test.py
+++ b/parameterized/test.py
@@ -2,12 +2,11 @@
import inspect
from unittest import TestCase
-from nose.tools import assert_equal
-from nose.plugins.skip import SkipTest
+from nose.tools import assert_equal, assert_raises
from .parameterized import (
PY3, PY2, parameterized, param, parameterized_argument_value_pairs,
- short_repr, detect_runner,
+ short_repr, detect_runner, SkipTest
)
def assert_contains(haystack, needle):
@@ -219,20 +218,25 @@
try:
parameterized([])(lambda: None)
except ValueError as e:
- assert_contains(str(e), "Parameters iterable was empty")
+ assert_contains(str(e), "iterable is empty")
else:
raise AssertionError("Expected exception not raised")
+def test_skip_test_on_empty_iterable():
+ func = parameterized([], skip_on_empty=True)(lambda: None)
+ assert_raises(SkipTest, func)
-try:
- class ExpectErrorOnEmptyInput(TestCase):
- @parameterized.expand([])
- def test_expect_error(self):
- pass
-except ValueError as e:
- assert_contains(str(e), "input was empty")
-else:
- raise AssertionError("Expected exception not raised")
+
+def test_helpful_error_on_empty_iterable_input_expand():
+ try:
+ class ExpectErrorOnEmptyInput(TestCase):
+ @parameterized.expand([])
+ def test_expect_error(self):
+ pass
+ except ValueError as e:
+ assert_contains(str(e), "iterable is empty")
+ else:
+ raise AssertionError("Expected exception not raised")
expect("generator", [