【问题标题】:Is there a way to configure Python logging to log content or context of assert failures?有没有办法配置 Python 日志记录以记录断言失败的内容或上下文?
【发布时间】:2013-08-07 23:21:31
【问题描述】:

我正在运行测试用例,我想设置我的日志记录,以便它自动记录所有测试失败的情况 - 但我想获得自定义响应,例如,如果断言失败我想得到对我的测试发出的请求的响应,而不仅仅是断言失败的默认消息。目前只知道断言失败,不知道程序返回了什么。

假设我正在测试一个视图函数,例如我有一个看起来大致像这样的测试(整个 TestCase 类的一部分)

def edit_profile(self):
    return self.app.get("/edit_profile", follow_redirects=True)

def test_edit_profile(self):
    rv = self.edit_profile()
    assert "Edit your profile admin" in rv.data

我有没有办法配置日志记录,使每次测试失败都会将 rv.data 记录到日志文件中?

目前我只是在之前测试中失败的断言之前添加 logging.debug(rv.data) ,再次运行测试,调试问题,然后继续,但这无效,很容易忘记那些日志记录。 debug() 稍后,如果我有一个功能可以在测试请求失败时自动记录我的网页响应,这会更快。

【问题讨论】:

    标签: python testing logging flask assertions


    【解决方案1】:

    考虑将 assert 替换为非抛出检查:

    def log_assert(arg=None):
        caller = inspect.stack()[1]
        if arg is None:
            with open(caller[1], "r") as source_code:
                for n, line in enumerate(source_code):
                    if n >= caller[2] - 1:
                        arg = line.strip
                    break
        logger.error("[%s:%d - %s] %s" % (basename(caller[1]), caller[2], caller[3], arg))
    
    ...
    
    "Edit your profile admin" in rv.data or log_assert("profile: \"" + str(rv.data) + "\"")
    

    将打印:

    ERROR [TestCase.py:320 - test_edit_profile] profile: "View your profile admin"
    

    【讨论】:

      【解决方案2】:

      你可以这样做:

      def test_edit_profile(self):
          rv = self.edit_profile()
          try:
              assert "Edit your profile admin" in rv.data
          except AssertionError:
              # Do your logging here
      

      编辑:有人指出,这基本上取消了断言功能,因为断言由 except 块处理。欢迎提出建议。

      编辑:这可行,但很草率。

      def test_edit_profile(self):
          rv = self.edit_profile()
          try:
              assert "Edit your profile admin" in rv.data
          except AssertionError:
              assert "Edit your profile admin" in rv.data
              # Do your logging here
      

      【讨论】:

      • 好的,这听起来很有趣,但是我不会在控制台输出失败,对吧?失败会被包裹在try中,除了block,不看日志就不知道失败了?
      • 天哪,我没想到……你说得对。那么一定有更好的方法来做到这一点。
      • 您可以使用 2 参数 assert 或使用 raise 重新引发异常,但无论如何您都不应该在 unittest 测试用例中使用 assert
      • 是的,我正在考虑是否再次声明它/在 except 块中引发错误。
      【解决方案3】:
      self.assertIn('Edit your profile admin', rv.data, msg=rv.data)
      

      使用assertWhatever 方法。我不完全明白为什么,但你不应该在unittest 中使用assert 语句来断言。 (其他框架允许您使用assert 进行断言。)

      作为参考,将消息添加到assert 断言的工作原理如下:

      assert 'Edit your profile admin' in rv.data, rv.data
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-27
        • 1970-01-01
        • 1970-01-01
        • 2020-07-11
        • 2012-04-13
        • 2018-03-11
        相关资源
        最近更新 更多