单元测试九:一些测试示例
green测试框架,但是有很多测试用例:https://github.com/CleanCut/green/
对loggin的测试示例:https://github.com/facundobatista/logassert/

# coding=utf-8 import collections import functools import logging.handlers Record = collections.namedtuple("Record", "levelname levelno message") class SetupLogChecker(logging.handlers.MemoryHandler): """A fake handler to store the records.""" def __init__(self, test_instance, log_path): # init memory handler to never flush super(SetupLogChecker, self).__init__(capacity=100000, flushLevel=1000) self.test_instance = test_instance test_instance.assertLogged = self._check_generic_pos test_instance.assertLoggedError = functools.partial(self._check_pos, logging.ERROR) test_instance.assertLoggedWarning = functools.partial(self._check_pos, logging.WARNING) test_instance.assertLoggedInfo = functools.partial(self._check_pos, logging.INFO) test_instance.assertLoggedDebug = functools.partial(self._check_pos, logging.DEBUG) test_instance.assertNotLogged = functools.partial(self._check_neg, None) test_instance.assertNotLoggedError = functools.partial(self._check_neg, logging.ERROR) test_instance.assertNotLoggedWarning = functools.partial(self._check_neg, logging.WARNING) test_instance.assertNotLoggedInfo = functools.partial(self._check_neg, logging.INFO) test_instance.assertNotLoggedDebug = functools.partial(self._check_neg, logging.DEBUG) # hook in the logger logger = logging.getLogger(log_path) logger.addHandler(self) logger.setLevel(logging.DEBUG) self.setLevel(logging.DEBUG) # hold a kind of record with the message already composed self.records = [] def emit(self, record): """Store the message, not only the record.""" self.records.append(Record(levelno=record.levelno, levelname=record.levelname, message=self.format(record))) return super(SetupLogChecker, self).emit(record) def _check_generic_pos(self, *tokens): """Check if the different tokens were logged in one record, any level.""" for record in self.records: if all(token in record.message for token in tokens): return # didn't exit, all tokens are not present in the same record msgs = ["Tokens {} not found, all was logged is...".format(tokens)] for record in self.records: msgs.append(" {:9s} {!r}".format(record.levelname, record.message)) self.test_instance.fail("\n".join(msgs)) def _check_pos(self, level, *tokens): """Check if the different tokens were logged in one record, assert by level.""" for record in self.records: if all(record.levelno == level and token in record.message for token in tokens): return # didn't exit, all tokens are not present in the same record level_name = logging.getLevelName(level) msgs = ["Tokens {} not found in {}, all was logged is...".format(tokens, level_name)] for record in self.records: msgs.append(" {:9s} {!r}".format(record.levelname, record.message)) self.test_instance.fail("\n".join(msgs)) def _check_neg(self, level, *tokens): """Check that the different tokens were NOT logged in one record, assert by level.""" for record in self.records: if level is not None and record.levelno != level: continue if all(token in record.message for token in tokens): break else: return # didn't exit, all tokens found in the same record msg = "Tokens {} found in the following record: {} {!r}".format( tokens, record.levelname, record.message) self.test_instance.fail(msg) def setup(test_instance, logger_name): """Set up the log monitoring. The test instance is the one where this will be used. The logger name is the one of the logger to supervise. Example of use: class MyTestCase(unittest.TestCase): def setUp(self): setup(self, 'mylogger') def test_blah(self): (...) self.assertLogged(...) """ return SetupLogChecker(test_instance, logger_name) import logging import unittest class FakeTestCase: """A fake to record if stuff failed.""" def __init__(self): self.failed = None def fail(self, text): self.failed = text class BasicUsageTestCase(unittest.TestCase): """Basic usage.""" def setUp(self): self.logger = logging.getLogger() self.logger.handlers = [] def test_get_handler(self): ftc = FakeTestCase() h = setup(ftc, '') self.assertIsInstance(h, logging.Handler) def test_simple_assert_ok(self): ftc = FakeTestCase() setup(ftc, '') self.logger.debug("test") ftc.assertLogged("test") self.assertEqual(ftc.failed, None) def test_simple_assert_ok_extras(self): ftc = FakeTestCase() setup(ftc, '') formatter = logging.Formatter("%(message)s %(foo)s") for h in self.logger.handlers: h.setFormatter(formatter) self.logger.debug("test", extra={'foo': 'bar'}) ftc.assertLogged("test bar") self.assertEqual(ftc.failed, None) def test_simple_assert_ok_with_replaces(self): ftc = FakeTestCase() setup(ftc, '') self.logger.debug("test %d %r", 65, 'foobar') ftc.assertLogged("test", "65", "foobar") self.assertEqual(ftc.failed, None) def test_simple_assert_fail(self): ftc = FakeTestCase() setup(ftc, '') self.logger.debug("test") ftc.assertLogged("test2") self.assertEqual(ftc.failed, "Tokens ('test2',) not found, all was logged is...\n" " DEBUG 'test'") def test_simple_assert_fail_with_replaces(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.debug("test %d %r", 65, 'foobar') ftc.assertLogged("test", "pumba") self.assertEqual(ftc.failed, "Tokens ('test', 'pumba') not found, all was logged is...\n" " DEBUG \"test 65 'foobar'\"") def test_avoid_delayed_messaging(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') class Exploding: """Explode on delayed str.""" should_explode = False def __str__(self): if self.should_explode: raise ValueError("str exploded") return "didn't explode" # log something using the Exploding class exploding = Exploding() logger.debug("feeling lucky? %s", exploding) # now flag the class to explode and check exploding.should_explode = True ftc.assertLogged("feeling lucky", "didn't explode") class LevelsTestCase(unittest.TestCase): """Work aware of logging levels.""" def test_assert_different_level_ok_debug(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.debug("test") ftc.assertLoggedDebug("test") self.assertEqual(ftc.failed, None) def test_assert_different_level_ok_info(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.info("test") ftc.assertLoggedInfo("test") self.assertEqual(ftc.failed, None) def test_assert_different_level_ok_error(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.error("test") ftc.assertLoggedError("test") self.assertEqual(ftc.failed, None) def test_assert_different_level_ok_exception(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') try: raise ValueError("test error") except: logger.exception("test message") ftc.assertLoggedError("test error") ftc.assertLoggedError("test message") ftc.assertLoggedError("ValueError") self.assertEqual(ftc.failed, None) def test_assert_different_level_ok_warning(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.warning("test") ftc.assertLoggedWarning("test") self.assertEqual(ftc.failed, None) def test_assert_different_level_fail_oneway(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.warning("test") ftc.assertLoggedDebug("test") self.assertEqual(ftc.failed, "Tokens ('test',) not found in DEBUG, all was logged is...\n" " WARNING 'test'") def test_assert_different_level_fail_inverse(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.debug("test") ftc.assertLoggedWarning("test") self.assertEqual( ftc.failed, "Tokens ('test',) not found in WARNING, all was logged is...\n" " DEBUG 'test'") class NotLoggedTestCase(unittest.TestCase): """Also check that it wasn't logged.""" def test_simple_ok(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.debug("test") ftc.assertNotLogged("other") self.assertEqual(ftc.failed, None) def test_simple_fail(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.info("test") ftc.assertNotLogged("test") self.assertEqual(ftc.failed, "Tokens ('test',) found in the following record: INFO 'test'") def test_level_debug_ok(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.info("test") ftc.assertNotLoggedDebug("test") self.assertEqual(ftc.failed, None) def test_level_debug_fail(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.debug("test") ftc.assertNotLoggedDebug("test") self.assertEqual(ftc.failed, "Tokens ('test',) found in the following record: DEBUG 'test'") def test_level_info(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.debug("test") ftc.assertNotLoggedInfo("test") self.assertEqual(ftc.failed, None) def test_level_warning(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.info("test") ftc.assertNotLoggedWarning("test") self.assertEqual(ftc.failed, None) def test_level_error(self): ftc = FakeTestCase() logger = logging.getLogger() setup(ftc, '') logger.info("test") ftc.assertNotLoggedError("test") self.assertEqual(ftc.failed, None)
多个装饰器的测试示例:https://github.com/mschwager/memunit
网络编程基础和单元测试:https://github.com/liuxingrichu/python-learn-log
posted on 2018-09-07 11:25 myworldworld 阅读(140) 评论(0) 收藏 举报