How do you generate dynamic (parameterized) unit tests in python?

后端 未结 25 2090
面向向阳花
面向向阳花 2020-11-22 07:09

I have some kind of test data and want to create a unit test for each item. My first idea was to do it like this:

import unittest

l = [[\"foo\", \"a\", \"a\         


        
相关标签:
25条回答
  • 2020-11-22 07:22

    You can use TestSuite and custom TestCase classes.

    import unittest
    
    class CustomTest(unittest.TestCase):
        def __init__(self, name, a, b):
            super().__init__()
            self.name = name
            self.a = a
            self.b = b
    
        def runTest(self):
            print("test", self.name)
            self.assertEqual(self.a, self.b)
    
    if __name__ == '__main__':
        suite = unittest.TestSuite()
        suite.addTest(CustomTest("Foo", 1337, 1337))
        suite.addTest(CustomTest("Bar", 0xDEAD, 0xC0DE))
        unittest.TextTestRunner().run(suite)
    
    0 讨论(0)
  • 2020-11-22 07:22

    This solution works with unittest and nose for Python 2 and Python 3:

    #!/usr/bin/env python
    import unittest
    
    def make_function(description, a, b):
        def ghost(self):
            self.assertEqual(a, b, description)
        print(description)
        ghost.__name__ = 'test_{0}'.format(description)
        return ghost
    
    
    class TestsContainer(unittest.TestCase):
        pass
    
    testsmap = {
        'foo': [1, 1],
        'bar': [1, 2],
        'baz': [5, 5]}
    
    def generator():
        for name, params in testsmap.iteritems():
            test_func = make_function(name, params[0], params[1])
            setattr(TestsContainer, 'test_{0}'.format(name), test_func)
    
    generator()
    
    if __name__ == '__main__':
        unittest.main()
    
    0 讨论(0)
  • 2020-11-22 07:22

    Besides using setattr, we can use load_tests since python 3.2. Please refer to blog post blog.livreuro.com/en/coding/python/how-to-generate-discoverable-unit-tests-in-python-dynamically/

    class Test(unittest.TestCase):
        pass
    
    def _test(self, file_name):
        open(file_name, 'r') as f:
            self.assertEqual('test result',f.read())
    
    def _generate_test(file_name):
        def test(self):
            _test(self, file_name)
        return test
    
    def _generate_tests():
        for file in files:
            file_name = os.path.splitext(os.path.basename(file))[0]
            setattr(Test, 'test_%s' % file_name, _generate_test(file))
    
    test_cases = (Test,)
    
    def load_tests(loader, tests, pattern):
        _generate_tests()
        suite = TestSuite()
        for test_class in test_cases:
            tests = loader.loadTestsFromTestCase(test_class)
            suite.addTests(tests)
        return suite
    
    if __name__ == '__main__':
        _generate_tests()
        unittest.main()
    
    0 讨论(0)
  • 2020-11-22 07:23

    There's also Hypothesis which adds fuzz or property based testing: https://pypi.python.org/pypi/hypothesis

    This is a very powerful testing method.

    0 讨论(0)
  • 2020-11-22 07:23

    Just to throw another solution in the mix ;)

    This is effectively the same as parameterized as mentioned above, but specific to unittest:

    def sub_test(param_list):
        """Decorates a test case to run it as a set of subtests."""
    
        def decorator(f):
    
            @functools.wraps(f)
            def wrapped(self):
                for param in param_list:
                    with self.subTest(**param):
                        f(self, **param)
    
            return wrapped
    
        return decorator
    

    Example usage:

    class TestStuff(unittest.TestCase):
        @sub_test([
            dict(arg1='a', arg2='b'),
            dict(arg1='x', arg2='y'),
        ])
        def test_stuff(self, a, b):
            ...
    
    0 讨论(0)
  • 2020-11-22 07:24

    You would benefit from trying the TestScenarios library.

    testscenarios provides clean dependency injection for python unittest style tests. This can be used for interface testing (testing many implementations via a single test suite) or for classic dependency injection (provide tests with dependencies externally to the test code itself, allowing easy testing in different situations).

    0 讨论(0)
提交回复
热议问题