On Nov 22, 11:38 am, Ulrich Eckhardt <ulrich.eckha...@dominolaser.com> wrote: > Hi! > > I'm writing tests and I'm wondering how to achieve a few things most > elegantly with Python's unittest module. > > Let's say I have two flags invert X and invert Y. Now, for testing these, I > would write one test for each combination. What I have in the test case is > something like this: > > def test_invert_flags(self): > """test flags to invert coordinates""" > tests = [((10, 20), INVERT_NONE, (10, 20)), > ((10, 20), INVERT_X, (-10, 20)), > ((10, 20), INVERT_Y, (10, -20))] > for input, flags, expected in tests: > res = do_invert(input, flags) > self.assertEqual(res, expected, > "%s caused wrong results" % (flags,)) > > So, what I do that I test the function 'do_invert' for different input > combinations and verify the result. The ugly thing is that this will abort > the whole test if one of the tests in the loop fails. So, my question is > how do I avoid this? > > I know that I could write a common test function instead: > > def _test_invert_flags(self, input, flags, expected): > res = do_invert(input, flags) > self.assertEqual(res, expected) > > def test_invert_flags_non(self): > """test not inverting coordinates""" > self._test_invert_flags((10, 20), INVERT_NONE, (10, 20)) > > def test_invert_flags_x(self): > """test inverting X coordinates""" > self._test_invert_flags((10, 20), INVERT_X, (-10, 20)) > > def test_invert_flags_y(self): > """test inverting Y coordinates""" > self._test_invert_flags((10, 20), INVERT_Y, (10, -20)) > > What I don't like here is that this is unnecessarily verbose and that it > basically repeats information. Also, I'd rather construct the error message > from the data instead of maintaining it in different places, because > manually keeping those in sync is another, errorprone burden. > > Any suggestions? > > Uli > > -- > Domino Laser GmbH > Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
The following is a bit ghastly, I'm not sure I'd recommend it, but if you are determined, you could try dynamically adding test methods to the test class. The following is untested - I suspect I have made a schoolboy error in attempting to make methods out of functions - but something like it might work: class MyTestClass(unittest.TestCase): pass testdata = [ (INPUTS, EXPECTED), (INPUTS, EXPECTED), (INPUTS, EXPECTED), ] for index, (input, expected) in enumerate(testdata): # the following sets an attribute on MyTestClass # the names of the attributes are 'test_1', 'test_2', etc # the value of the attributes is a test method that performs the assert setattr( MyTestClass, 'test_%d' % (index,), lambda s: s.assertEquals(METHOD_UNDER_TEST(*input), expected) ) -- http://mail.python.org/mailman/listinfo/python-list