Unittest - How do I code lots of simple tests

Ian Bicking ianb at colorstudy.com
Tue Oct 21 18:20:10 EDT 2003


On Tuesday, October 21, 2003, at 04:32 PM, Peter Hansen wrote:
> Paul Moore wrote:
>> Can anyone suggest a more reasonable way of running this sort of
>> table-driven test via unittest?
>
> Why not just extend self.assertEqual() and use your own check, with
> additional logic as required to increment counters or add items
> to the list of passing tests.  Then put a final check of the number
> of passing tests or something like that at the end to make sure
> things worked overall.
> For example:
>
> class KnownValues(unittest.TestCase):
>     def setUp(self):
>         self.passCount = 0
>
>     def checkValue(self, expected, result):
>         if expected == result:
>             self.passCount += 1
>         else:
>             # left as exercise to the reader, but pass would work...
>
>     def testToRomanKnownValues(self):
>         for integer, numeral in self.knownValues:
>             result = roman.toRoman(integer)
>             self.checkValue(numeral, result)
>         self.assertEqual(len(self.knownValues), self.passCount)
>
> No, you don't get the psychologically affirming "52 tests passed!"
> without changes to the TestRunner, but I assume the non-cosmetic part
> of this is more your concern right now...

This will still abort if toRoman raises an exception (you'll just get 
one exception, not all exceptions or failures, and you won't know if 
previous conversions didn't pass but didn't cause an exception).  Also, 
you won't be able to run a specific test, you'll have to run the whole 
set -- obviously not a big deal for this, but other tests might be more 
time consuming.

You can do something like:

class RomanTest(unittest.TestCase):
     def __init__(self, source, expected):
         self.expected = expected
         self.result = result
     def test(self):
         self.assertEqual(expected, roman.toRoman(source))

def createSuite():
     suite = unittest.TestSuite()
     for i, v in knownValues:
         suite.addTest(RomanTest(i, v))

if __name__ == '__main__':
     unittest.main(defaultTest='createSuite')


You still can't name tests this way.  I've tried to name tests, but 
unittest.main won't pay attention to my names.  unittest is not written 
with subclassing in mind, except for the limited subclassing that is 
documented.  (And it uses double-underscore variables, like it's just 
*trying* to piss me off!  Double-underscore variables are so arrogant 
and patronizing.  But maybe I'm a little more bothered by this right 
now because I'm not in a good mood).

--
Ian Bicking | ianb at colorstudy.com | http://blog.ianbicking.org






More information about the Python-list mailing list