Python 2.7单元测试检查是否记录了警告

Python 2.7单元测试检查是否记录了警告,python,python-2.7,python-unittest,python-logging,Python,Python 2.7,Python Unittest,Python Logging,我正在尝试为我的模块编写一个用Python2.7编写的单元测试,我现在无法迁移到3.x。对于这个测试,我想要做的是检查我的模块是否生成了警告日志,如果生成了,则捕获它。通过搜索web和堆栈溢出,我找不到Python2.7的答案。我已经包含了一个简单的可测试代码,您可以使用它来尝试一些东西,或者更好地理解我的问题 更新: 为了澄清,我愿意更改我的测试用例,即test\u warning\u 2,以便能够捕获log.warn该方法的当前实现只是一个占位符 导入日志 进口警告 从unittest导入T

我正在尝试为我的模块编写一个用Python2.7编写的单元测试,我现在无法迁移到3.x。对于这个测试,我想要做的是检查我的模块是否生成了警告日志,如果生成了,则捕获它。通过搜索web和堆栈溢出,我找不到Python2.7的答案。我已经包含了一个简单的可测试代码,您可以使用它来尝试一些东西,或者更好地理解我的问题

更新: 为了澄清,我愿意更改我的测试用例,即
test\u warning\u 2
,以便能够捕获
log.warn
该方法的当前实现只是一个占位符

导入日志
进口警告
从unittest导入TestCase
def生成警告2()
logging.warn(“这是一个警告”)
def生成警告1()
警告。警告(“这是一个警告”)
类TestWarning(TestCase):
def测试警告1(自身):
警告:simplefilter(“始终”)
带有警告。捕获警告(记录=True)为w:
生成\u警告\u 1()
自组装质量(len(w),1)
def测试警告2(自身):
#下面的代码只是一个占位符,我需要一些代码来替换它,这样我就可以捕获'log.warn'`
警告:simplefilter(“始终”)
带有警告。捕获警告(记录=True)为w:
生成_警告_2()
自组装质量(len(w),1)
在这里,如果您看到函数
generate_warning_2
,您会注意到我使用的是传统的python日志记录警告,这不是我的测试用例所捕获的。我知道原因是因为它没有使用
警告
模块。我只是想展示我想要它做什么

另一个功能是
generate_warning_1
我使用
warnings
模块捕获警告日志,这是我当前的实现,运行良好

我希望能够捕获
log.warn
,而不必使用
warning
来实现这一点。这在Python2.7中可能吗?请不要提供Python3.x的答案,因为我已经知道这是可能的


希望我的问题是明确的,请随时问我的问题或编辑在适当的地方。非常感谢您的帮助。

这可以使用记录器处理程序解决。不幸的是,似乎无法在根记录器上设置处理程序,只能在
getLogger
返回的实例上设置。如果你能接受这一点,这应该是可行的:

import logging
import warnings
import unittest


class WarningsHandler(logging.Handler):
    def handle(self, record):
        if record.levelno == logging.WARN:
          warnings.warn(record.getMessage())
        return record

log = logging.getLogger()
log.addHandler(WarningsHandler())

def generate_warning_2():
    log.warn("this is a warning")


def generate_warning_1():
    warnings.warn("this is a warning")


class TestWarning(unittest.TestCase):

    def test_warning_1(self):
        warnings.simplefilter("always")
        with warnings.catch_warnings(record=True) as w:
            generate_warning_1()
            self.assertEquals(len(w), 1)

    def test_warning_2(self):
        warnings.simplefilter("always")
        with warnings.catch_warnings(record=True) as w:
            generate_warning_2()
            self.assertEquals(len(w), 1)

if __name__ == "__main__":
    unittest.main()


为了防止最终的双重打印,您可能希望处理程序只有条件地返回日志记录。

“我现在无法迁移到3.x。”最好尽快找到时间。2.7将于明年到期。另外,不要对日志操作进行单元测试。这不是一个宝贵的时间使用。我知道2.7即将结束,不迁移的决定不是我的。你把警告和日志级别的日志记录混淆了。这是两种截然不同的东西。你只是想测试你的日志代码是否有效,而
警告。catch_warnings()
对此无能为力。好的,然后看看重复的帖子,它正好涵盖了这个场景。谢谢你的回答,我已经考虑过类似的事情了。我现在想避免接触日志模块,如果可以的话,那么我可能误解了这个问题。您不希望在任何地方都使用
警告
模块,但是您也不想对
日志记录
模块做任何事情吗?我只是想澄清一下,如果有任何其他方法可以捕获
日志,我愿意更改函数
test\u warning\u 2
。warn
logging我不想更改日志记录模块,以便在测试用例中捕获警告。我主要希望以任何可能的方式在测试用例中捕获log.warn。即使这意味着更改
test\u warning\u 2
测试用例,该测试用例只是一个占位符,因为我不知道其他任何实现。@AJS只需修改代码,使
warningHandler
存储信息(例如,将消息存储在
warnings
实例变量中),并得到实例化,由测试用例添加和删除。这样,您可以在测试用例开始时设置处理程序,运行代码,删除处理程序,然后检查处理程序的内容。或者,将所有内容切换到pytest:它支持和内置。
$ python2 so.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK