| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- #
- # Python unit test runner
- #
- # Author : Sander Mathijs van Veen <smvv@kompiler.org>
- # License: GPL version 3, see also the file `LICENSE'.
- #
- import os
- import sys
- import time
- import unittest
- class TextTestRunner(unittest.TextTestRunner):
- """This is a wrapper class used to minimize the amount of blank lines
- printed to stdout. The method ``run`` is modified and it's original source
- is in Python Standard Library's ``unittest`` module."""
- def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1,
- color=True):
- unittest.TextTestRunner.__init__(self, stream, descriptions, verbosity)
- self.color = color
- def run(self, test):
- "Run the given test case or test suite."
- result = self._makeResult()
- result.failfast = getattr(self, 'failfast', None)
- result.buffer = getattr(self, 'buffer', None)
- startTime = time.time()
- startTestRun = getattr(result, 'startTestRun', None)
- if startTestRun is not None:
- startTestRun()
- try:
- test(result)
- finally:
- stopTestRun = getattr(result, 'stopTestRun', None)
- if stopTestRun is not None:
- stopTestRun()
- stopTime = time.time()
- timeTaken = stopTime - startTime
- result.printErrors()
- if not result.wasSuccessful():
- if self.color:
- msg = '\033[0;31mFAIL\033[1;m'
- else:
- msg = 'FAIL'
- self.stream.write(msg)
- else:
- if self.color:
- msg = '\033[0;32mOK\033[0;m'
- else:
- msg = 'OK'
- self.stream.write(msg)
- self.stream.write(' %s: %d test%s in %.3fs ' \
- % (test.filename, result.testsRun,
- result.testsRun != 1 and 's' or '', timeTaken))
- expectedFails = unexpectedSuccesses = skipped = 0
- try:
- results = map(len, (result.expectedFailures,
- result.unexpectedSuccesses,
- result.skipped))
- except AttributeError:
- pass
- else:
- expectedFails, unexpectedSuccesses, skipped = results
- infos = []
- if not result.wasSuccessful():
- failed, errored = map(len, (result.failures, result.errors))
- if failed:
- if self.color:
- msg = 'failures=\033[1;31m%d\033[1;m'
- else:
- msg = 'failures=%d'
- infos.append(msg % failed)
- if errored:
- if self.color:
- msg = 'errors=\033[1;31m%d\033[1;m'
- else:
- msg = 'errors=%d'
- infos.append(msg % errored)
- if skipped:
- if self.color:
- msg = 'skipped=\033[1;33m%d\033[1;m'
- else:
- msg = 'skipped=%d'
- infos.append(msg % skipped)
- if expectedFails:
- infos.append('expected failures=%d' % expectedFails)
- if unexpectedSuccesses:
- infos.append('unexpected successes=%d' % unexpectedSuccesses)
- if infos:
- self.stream.writeln(' (%s)' % (', '.join(infos),))
- else:
- self.stream.write('\n')
- return result
- def main(tests, verbose=0, color=True):
- testcases = []
- # Dynamic load the requested module containing the test cases.
- for testfile in tests:
- try:
- module_name = os.path.splitext(testfile)[0].replace('/', '.')
- module_obj = __import__(module_name)
- except:
- print 'testfile: ', testfile
- print 'module_name:', module_name
- raise
- # Start the test runner and display the results to stdout.
- try:
- suite_name = module_name.split('.')[-1]
- container = module_obj.__dict__[suite_name]
- except:
- print 'testfile: ', testfile
- print 'module_name:', module_name
- print 'module_obj: ', module_obj, dir(module_obj)
- raise
- # Convert lowercase, underscored suite name to Python class name.
- class_parts = suite_name[5:].split('_')
- class_name = 'Test' + ''.join([p.capitalize() for p in class_parts])
- testcase = container.__dict__[class_name]
- testcases += [unittest.TestLoader().loadTestsFromTestCase(testcase)]
- # Create the text runner and execute the tests.
- runner = TextTestRunner(verbosity=verbose, color=color)
- suite = unittest.TestSuite(testcases)
- suite.filename = testfile
- result = runner.run(suite)
- # Return non zero exit code if there are failures or errors occured.
- if result.failures or result.errors:
- sys.exit(1)
|