【问题标题】:Python logging module: how to save log to a file if (and only if) assertion test fails?Python日志记录模块:如果(且仅当)断言测试失败时如何将日志保存到文件?
【发布时间】:2019-09-01 16:53:49
【问题描述】:

我正在寻找一种优雅且 Pythonic 的解决方案,以使测试将日志保存到文件中,但 以防测试失败。我想保持简单,并坚持使用 Python 的内置 logging 模块。

我目前的解决方案是对每个测试的断言使用包装函数:

import unittest

class superTestCase(unittest.TestCase): 
    ...

    def assertWithLogging(self, assertion, assertion_arguments, expected_response, actual_response, *args):
        try:
            assertion(*assertion_arguments)
        except AssertionError as ae:
            test_name = inspect.stack()[1][3]
            current_date_time = datetime.datetime.now().strftime("%Y.%m.%d %H-%M-%S")
            logging.basicConfig(filename='tests/{}-{}-Failure.log'.format(current_date_time, test_name),
                                filemode='a',
                                format='%(message)s',
                                level=logging.DEBUG
                                )
            logger = logging.getLogger('FailureLogger')
            logger.debug('{} has failed'.format(test_name))
            logger.debug('Expected response(s):')
            logger.debug(expected_response)
            logger.debug('Actual response:')
            logger.debug(actual_response)
            for arg in args:
                logger.debug('Additionl logging info:')
                logger.debug(arg)
            raise ae

    def testSomething(self):
        ...

        self.assertWithLogging(self.assertEqual,
                               [expected_response, actual_response]
                               expected_response,
                               actual_response,
                               some_other_variable
                               )

虽然它按我的预期工作,但对我来说,这个解决方案似乎很笨拙而且不太Pythonic

  1. 什么是()更优雅的方式来实现相同的结果?
  2. 当前方法的缺点是什么?

【问题讨论】:

  • 我看不到任何方法可以覆盖所有各种断言方法的行为,因此包装函数可能是最好的方法。也就是说:(1)您应该将 basicConfig 完全移出该模块(如果已经配置了根记录器,它甚至不会做任何事情)并将 getLogger 调用移至模块级别; (2) 您不需要捕获当前时间,因为调试调用已经产生了(asctime 字段); (3) 我认为不需要重复 expected_response 和 actual_response - 这只会让每次调用 assertWithLogging 更加冗长。
  • @JoeP,感谢您的评论。我有一些后续问题:(1) 您是否打算将basicConfig 移至单独的模块(显然与import logging 一起),然后将此模块导入需要记录器的任何地方? (2) 我使用当前时间,使其成为日志文件名的一部分。是否可以将asctime 用作basicConfig(filename=...) 的一部分? (3) 您是否建议记录断言消息?因为现在,如果我删除 expected_responseactual_response 的日志记录,则只保留 someTest has failed

标签: python python-3.x python-2.7 unit-testing logging


【解决方案1】:

您可以使用各种日志记录机制,您可以在其中设置您想要实现的日志类型。

下面的将只记录错误消息。

Logger.error(msg, *args, **kwargs)

这会在此记录器上记录 msglevel logging.ERROR。参数被解释为debug()

【讨论】:

  • 感谢您的回答。我可能对我所问的内容不够准确。我正在寻找一种记录一些消息的方法(实际上将日志保存到文件中,在这种情况下这可能被认为是等效的)仅当测试断言失败时(不管消息的logging.level) .由于我无法在断言本身中添加logger 调用,因此我想出了问题中提出的包装器解决方案。虽然我觉得它很笨拙,所以我正在寻找更好的选择。我希望这个问题现在更有意义。
猜你喜欢
  • 2012-09-14
  • 2015-09-19
  • 1970-01-01
  • 1970-01-01
  • 2018-12-08
  • 1970-01-01
  • 2011-05-09
  • 2020-11-07
  • 2019-12-08
相关资源
最近更新 更多