I'm using unittest module. I need to separate setUp, setUpClass, teardown and teardownClass logs from unittests logs. Output should look something like:
**************setting things up**************
INFO: preparing database
INFO: create new users
**************end of setup****************
INFO: starting test one
INFO: ...
**************Cleaning things**************
INFO: delete users
...
I tried to override some functions in unittest.suite (_handleClassSetUp, _handleModuleFixtures, _tearDownPreviousClass) to log separators before and after they are called. As a result separators are logged even if test case does not contain setUpClass and tearDownClass. And still, there is no separator for setup and teardown.
How can it be done?
You could use a metaclass to achieve this functionality. All it's doing is looking for a list of function names that you provide, and then applying a decorator to those functions. The decorator handles printing entry and exit statements.
import functools
import unittest
FUNCTIONS_TO_LOG = ('setUp', 'tearDown')
def log_start_and_end(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
print '********** start {}'.format(f.__name__)
f(*args, **kwargs)
print '********** end {}'.format(f.__name__)
return wrapper
class LoggingMeta(type):
def __new__(cls, name, bases, namespace):
for attr, obj in namespace.items():
if attr in FUNCTIONS_TO_LOG:
namespace[attr] = log_start_and_end(obj)
return super(LoggingMeta, cls).__new__(cls, name, bases, namespace)
class BaseTest(unittest.TestCase):
__metaclass__ = LoggingMeta
def setUp(self):
print 'inside setup'
def tearDown(self):
print 'inside teardown'
def test_test(self):
print 'inside test'
if __name__ == '__main__':
unittest.main()
This results in output:
********** start setUp
inside setup
********** end setUp
inside test
********** start tearDown
inside teardown
********** end tearDown
.
Ran 1 test in 0.000s
OK