Created
March 27, 2016 23:00
-
-
Save simonw/6aaab51f84f163f3a675 to your computer and use it in GitHub Desktop.
Parameterized unit tests for Python - syntactic sugar inspired by https://chris-lamb.co.uk/posts/generating-dynamic-python-tests-using-metaclasses
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class ParameterizedTestsMeta(type): | |
| def __new__(cls, name, bases, attrs): | |
| skip_these_names = [] | |
| i = 1 | |
| for name, fn in attrs.items(): | |
| if name.startswith('test_') and callable(fn) and getattr(fn, '_parameterized_params', None): | |
| skip_these_names.append(name) | |
| for params in fn._parameterized_params: | |
| attrs['%s_%d' % (name, i)] = cls.make_parameterized_test(fn, params) | |
| i += 1 | |
| new_attrs = dict([ | |
| pair for pair in attrs.items() if pair[0] not in skip_these_names | |
| ]) | |
| return super(ParameterizedTestsMeta, cls).__new__(cls, name, bases, new_attrs) | |
| @classmethod | |
| def make_parameterized_test(cls, fn, params): | |
| def test_fn(self): | |
| fn(self, params) | |
| return test_fn | |
| def parameterized(*params): | |
| def decorator(fn): | |
| fn._parameterized_params=params | |
| return fn | |
| return decorator |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import unittest | |
| from parameterized import ParameterizedTestsMeta, parameterized | |
| class DoubleTests(unittest.TestCase): | |
| __metaclass__ = ParameterizedTestsMeta | |
| @parameterized( | |
| (5, 10), | |
| (6, 12), | |
| (20, 40), | |
| ) | |
| def test_double(self, (input, expected)): | |
| self.assertEqual(expected, double(input)) | |
| # The function we are testing | |
| def double(i): | |
| return i * 2 | |
| if __name__ == '__main__': | |
| unittest.main() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here's example output if we add another pair to the parameterized list of
(30, 31):