dynamic unittest

Peter Otten __peter__ at web.de
Mon Jul 17 02:50:31 EDT 2006


Oleg  Paraschenko wrote:

> Hello,
> 
> I decided to re-use functionality of "unittest" module for my purposes.
> More precisely, I have a list of folders. For each folder, code should
> enter to the folder, execute a command and assert the output. It's
> reasonable to use "unittest" here, but the problem is that "unittest"
> doesn't support (== I haven't found how) dynamic creation of tests.
> 
> I thought it would be very easy, but due to lack of closures in Python
> (more precisely, closures do exist, but they are counter-intuitive for
> lisp programmers), I failed. Finally, I found a way using a global
> variable. I exploit the fact that "unittest" uses "cmp" to arrange test
> cases. Therefore, if we have an array of test names and sequential
> number of running the common function, we know the name of the current
> test. Here is a sample code:
> 
> ------- <dynamic_unittest.py>
> 
> import sys, unittest
> test_names = ['aaa', 'ddd', 'bbb']
> test_names.sort()
> test_index = 0
> 
> class DynamicTestCase(unittest.TestCase):
>   def one_test(self):
>     global test_index
>     test_name  = test_names[test_index]
>     test_index = test_index + 1
>     # Ok for 'aaa' and 'bbb', failure for 'ddd'
>     assert test_name in ['aaa', 'bbb']
> 
> for test_name in test_names:
>   func_name = 'test_' + test_name
>   setattr(DynamicTestCase, func_name, DynamicTestCase.one_test)
> 
> suite = unittest.makeSuite(DynamicTestCase, 'test_')
> if not unittest.TextTestRunner().run(suite).wasSuccessful():
>   sys.exit(1)
> 
> ------- </dynamic_unittest.py>
> 
> I think this code might help others, so I post it to the group.
> Comments are welcome.

Here's what your code might look like with closures:

import sys
import unittest

test_names = ['aaa', 'ddd', 'bbb']
test_names.sort()

class DynamicTestCase(unittest.TestCase):
    pass

def make_test(test_name):
    def one_test(self):
        self.assert_(test_name in ['aaa', 'bbb'])
    return one_test

for test_name in test_names:
    setattr(DynamicTestCase, 'test_' + test_name, make_test(test_name))

if __name__ == "__main__":
    unittest.main()

Peter



More information about the Python-list mailing list