Parameterized
Parameterized is a Python library that provides parameterized testing capabilities for various test frameworks like unittest, pytest, and nose. It simplifies writing data-driven tests by allowing the same test logic to be run with multiple sets of input data, reducing duplication and improving test coverage. The current version is 0.9.0, released in March 2023.
Warnings
- breaking As of version 0.9.0, `parameterized` has dropped support for Python 2.x, 3.5, and 3.6. If you require these Python versions, you must use an older version of `parameterized` (e.g., 0.8.1).
- gotcha When combining `@parameterized` (or `@parameterized.expand`) with `@mock.patch`, the `@mock.patch` decorator must be placed *below* the `@parameterized` decorator. Additionally, the arguments introduced by `mock.patch` should appear *last* in the test method's signature. Incorrect ordering can lead to unexpected behavior or errors.
- gotcha If you use an iterator or generator to supply parameters to `@parameterized` or `@parameterized.expand`, all items will be loaded into memory *before* the test run begins. This can be a significant memory concern for very large or infinite parameter sets.
- gotcha A common pitfall is installing `parametrized` (missing the 'e') instead of `parameterized`. This will result in an `AttributeError: 'function' object has no attribute 'expand'` when trying to use `parameterized.expand`.
- gotcha Overcomplicating parameterized test cases with excessive parameters or too many variations within a single test can lead to confusion, difficulty in maintenance, and unclear results. This defeats the purpose of parameterized testing.
Install
-
pip install parameterized
Imports
- parameterized
from parameterized import parameterized
- param
from parameterized import param
- parameterized_class
from parameterized import parameterized_class
Quickstart
import unittest
from parameterized import parameterized, param
import math
class TestMath(unittest.TestCase):
@parameterized([
(2, 2, 4),
(2, 3, 8),
(1, 9, 1),
(0, 9, 0),
])
def test_pow(self, base, exponent, expected):
self.assertEqual(math.pow(base, exponent), expected)
@parameterized.expand([
("negative", -1.5, -2.0),
("integer", 1, 1.0),
("large fraction", 1.6, 1),
])
def test_floor(self, name, input_val, expected):
self.assertEqual(math.floor(input_val), expected)
@parameterized_class(('a', 'b', 'expected_sum'), [
(1, 2, 3),
(5, 5, 10),
])
class TestMathClass(unittest.TestCase):
def test_add(self):
self.assertEqual(self.a + self.b, self.expected_sum)
# To run these tests, you would typically use:
# unittest.main(argv=['first-arg-is-ignored'], exit=False)
# or a test runner like pytest/nose.