【问题标题】:Assert that logging has been called with specific string断言已使用特定字符串调用日志记录
【发布时间】:2015-10-22 02:09:03
【问题描述】:

我正在尝试使用unittest 来测试我制作的 SimpleXMLRPCServer 的一些功能。与 Mock 一起,我现在试图断言在到达 if 语句时已记录特定消息,但我无法让它工作。我已经尝试实现我在 StackOverflow 或谷歌搜索上找到的各种答案,但仍然没有运气。我在测试用例中的调用如下:

def test_listen_for_tasks(self):
    el = {'release': 'default', 'component': None}
    for i in range(50):
        self.server._queue.put(el)
    ServerThread.listen_for_tasks(self.server, 'bla', 'blabla')
    with mock.patch('queue_server.logging') as mock_logging:
        mock_logging.warning.assert_called_with('There are currently {}'
                                                ' items in the queue'.format(
                                                 str(len(self.server._queue.queue))))

服务器中的功能如下:

def listen_for_tasks(self, release, component):
    item = {'release': release, 'component': component}
    for el in list(self._queue.queue):
        if self.is_request_duplicate(el, item):
            logger.debug('Already have a request'
                         ' for this component: {}'.format(item))
            return
    self._queue.put(item, False)
    if len(self._queue.queue) > 50:
        logger.warning('There are currently {}'
                       ' items in the queue'.format(
                        str(len(self._queue.queue))))

知道为什么这不起作用吗?我是 Python 单元测试的新手,并且断言记录器已经完成了某些事情似乎是一个人可能面临的最大问题,所以我可能在代码中搞砸了一些非常简单的事情。任何形式的帮助将不胜感激!

编辑:为了完整起见,这里是测试输出和失败:

.No handlers could be found for logger "queue_server"
F


FAIL: test_listen_for_tasks (__main__.TestQueueServer)

Traceback (most recent call last):
  File "artifacts_generator/test_queue_server.py", line 46, in   test_listen_for_tasks
str(len(self.server._queue.queue))))
  File "/home/lugiorgi/Desktop/Code/publisher/env/local/lib/python2.7/site-packages/mock/mock.py", line 925, in assert_called_with
raise AssertionError('Expected call: %s\nNot called' % (expected,))
AssertionError: Expected call: warning('There are currently 51 items in the queue')
Not called

Ran 2 tests in 0.137s

FAILED (failures=1)

【问题讨论】:

    标签: python-2.7 unit-testing logging mocking python-unittest


    【解决方案1】:

    从python 3.4开始可以使用unittest.TestCase类方法assertLogs

    import logging
    import unittest
    
    
    class LoggingTestCase(unittest.TestCase):
        def test_logging(self):
            with self.assertLogs(level='INFO') as log:
                logging.info('Log message')
                self.assertEqual(len(log.output), 1)
                self.assertEqual(len(log.records), 1)
                self.assertIn('Log message', log.output[0])
    

    【讨论】:

      【解决方案2】:

      您需要首先模拟对象,然后调用您要测试的函数。

      在模拟对象时,您还需要提供要模拟的对象的完整包和对象/函数名称,而不是变量名称。

      最后,使用 patch 的装饰器形式通常更方便。

      所以,例如:

      logger = logging.getLogger(__name__)
      
      def my_fancy_function():
          logger.warning('test')
      
      @patch('logging.Logger.warning')
      def test_my_fancy_function(mock):
          my_fancy_function()
          mock.assert_called_with('test')
      
      # if you insist on using with:
      def test_my_fancy_function_with_with():
          with patch('logging.Logger.warning') as mock:
              my_fancy_function()
              mock.assert_called_with('test')
      

      【讨论】:

      • 由于这是为 Python 2.7 标记的,因此完整的答案应该在 github.com/testing-cabal/mock 处提及 backport,而这不是其内置模块的一部分。
      • 这会导致比它解决的问题更多的问题,因为如果你模拟你的记录器,它会隐藏你所有的日志信息,使得诊断单元测试失败变得非常困难。您应该使用带有 wraps 选项的 patch.object() 来允许记录通过,这样您仍然有一个功能性记录器。
      猜你喜欢
      • 2023-03-11
      • 1970-01-01
      • 2016-05-28
      • 1970-01-01
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      • 2014-04-12
      • 1970-01-01
      相关资源
      最近更新 更多