单元测试九:一些测试示例

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)
View Code

多个装饰器的测试示例:https://github.com/mschwager/memunit

网络编程基础和单元测试:https://github.com/liuxingrichu/python-learn-log

 

posted on 2018-09-07 11:25  myworldworld  阅读(140)  评论(0)    收藏  举报

导航