Ticket #17958: capture_logging.diff

File capture_logging.diff, 3.8 KB (added by Claude Paroz, 8 years ago)

Add context manager for logging capture

  • django/test/utils.py

    diff --git a/django/test/utils.py b/django/test/utils.py
    index ed5ab59..b97d98f 100644
    a b  
    11from __future__ import with_statement
    22
     3from contextlib import contextmanager
     4import logging
    35import warnings
     6
    47from django.conf import settings, UserSettingsHolder
    58from django.core import mail
    69from django.test.signals import template_rendered, setting_changed
    class override_settings(object): 
    221224            setting_changed.send(sender=settings._wrapped.__class__,
    222225                                 setting=key, value=new_value)
    223226
     227
     228@contextmanager
     229def capture_logging(logger_name=''):
     230    """
     231    Temporarily redirect logging to a buffer (list)
     232    """
     233    logger = logging.getLogger(logger_name)
     234    saved_handlers = logger.handlers[:]
     235    for handler in logger.handlers:
     236        logger.removeHandler(handler)
     237    capture_handler = logging.handlers.MemoryHandler(100)
     238    logger.addHandler(capture_handler)
     239
     240    try:
     241        yield capture_handler.buffer
     242    finally:
     243        logger.removeHandler(capture_handler)
     244        capture_handler.close()
     245        for handler in saved_handlers:
     246            logger.addHandler(handler)
  • docs/topics/testing.txt

    diff --git a/docs/topics/testing.txt b/docs/topics/testing.txt
    index 829e059..43892e9 100644
    a b under MySQL with MyISAM tables):: 
    18371837        def test_transaction_behavior(self):
    18381838            # ... conditional test code
    18391839
     1840Capturing logging during tests
     1841------------------------------
     1842
     1843.. versionadded:: 1.5
     1844
     1845.. currentmodule:: django.test
     1846
     1847.. function:: capture_logging(logger_name='')
     1848
     1849Django provides the ``capture_logging`` context manager as a way to allow you
     1850to capture the logging output during some tests. You can then access the
     1851logged content in the captured variable, as a list of
     1852:py:class:`LogRecord <logging.LogRecord>` objects.  Here's a usage example::
     1853
     1854    from django.test.utils import capture_logging
     1855
     1856    class MyTests(TestCase):
     1857        def test_containing_logging(self):
     1858            with capture_logging('logger.name') as log:
     1859                # ... Do stuff that output logging content
     1860                # ... Now output is a StringIO instance that contains logging output
     1861                self.assertEqual(log[0].msg, "First logging content")
     1862
     1863
    18401864Live test server
    18411865----------------
    18421866
  • tests/regressiontests/test_utils/tests.py

    diff --git a/tests/regressiontests/test_utils/tests.py b/tests/regressiontests/test_utils/tests.py
    index 7f4208c..9e5c2bc 100644
    a b  
    11# -*- coding: utf-8 -*-
    22from __future__ import with_statement, absolute_import
     3import logging
    34
    45from django.forms import EmailField, IntegerField
    56from django.http import HttpResponse
    __test__ = {"API_TEST": r""" 
    562563'<foo bbb="2.0" aaa="1.0">Hello</foo><bar ddd="4.0" ccc="3.0"></bar>'
    563564
    564565"""}
     566
     567
     568class CaptureLoggingTests(SimpleTestCase):
     569    def test_capture_logging(self):
     570        from django.test.utils import capture_logging
     571
     572        logger = logging.getLogger('django.request')
     573        previous_handlers = logger.handlers[:]
     574        with capture_logging('django.request') as log:
     575            logger.error("This is a test log output")
     576            self.assertEqual(log[0].msg, "This is a test log output")
     577
     578        # Test that original handlers are restored
     579        self.assertEqual(logger.handlers, previous_handlers)
     580
     581    def test_capture_root_logger(self):
     582        from django.test.utils import capture_logging
     583
     584        with capture_logging() as log:
     585            logging.warn("This is a test log output")
     586            self.assertEqual((log[0].levelno, log[0].msg),
     587                (logging.WARNING, "This is a test log output"))
Back to Top