Background
I'm trying to figure out how to run a single unittest against multiple input values and then display the failure. This is a trivial demo of the sort of thing I have in mind:
from time import time
import unittest
def demo():
while True:
count = 0
for i in xrange(10):
count += 1
yield int(time() * 1000) + count
count = 0
class TestDemo(unittest.TestCase):
def setUp(self):
self.gen = demo()
self.prev = next(self.gen)
def test_always_bigger(self):
for cycle in xrange(1000):
curr = next(self.gen)
self.assertGreater(curr, self.prev)
self.prev = curr
if __name__ == '__main__':
unittest.main()
The most similar questions I've found been answered with some sort of dynamic test_<something>
method creation (ex: 1, 2, 3) or nose generators (ex: 1, 2). I'm looking to run 1000s of iterations based on unpredictable input while sticking to the standard library so neither solution is a great fit. Simple looping (as shown above) works well with two limitations: for complex inputs there is an inadequate record of what caused the test to fail (my real problem); and, a single failure within the test_<...>
method fails the whole test.
Question
I can live with the early failure, but how can I get at the inputs causing a failure without creating thousands of lines of output on success?
Non-answer
I tried the assert...
method msg
kwarg but it really only works well for the sort of trivial cases the library already handles well. In the above example unittest knows to show the two long
s that caused the assertion failure. I could annotate that and provide a lot of insight into the failure with `self.assertGreater(curr, self.prev, msg="cycle %s" % cycle), but showing deeply nested dicts on an assertDictEquals is a mess.
Desirable Solution
This answer shows an interesting use of the logging module but would generate thousands of lines of output for each successful test. Is it possible to detect failure from within the test method? Something like:
def test_always_bigger(self):
for cycle in xrange(1000):
curr = next(self.gen)
fail = self.assertGreater(curr, self.prev)
if fail:
log.debug('...')
self.prev = curr