如何解决如何在单元测试下运行的 doctest 中抑制 ResourceWarning()s
我的 Python doctests 打开了一些它从不关闭的文件。这不会造成任何问题;当对象被销毁时它们会自动关闭,并且添加逻辑以确保它们被明确关闭会不必要地使我的文档复杂化。
然而,当 doctest 在 unittest
内运行时,它们开始发出 ResourceWarning()
,给我的输出添加无益的噪音。
例如,给定的leaks.py:
def hello(f):
"""
>>> a = open("test-file","w")
>>> hello(a)
>>> open("test-file").read()
'hello'
"""
f.write("hello")
f.flush()
def load_tests(loader,tests,ignore):
import doctest
tests.addTests(doctest.DocTestSuite())
return tests
在 doctest 和 unittest 下使用 Python 3.6.9 运行它会生成:
$ python3 --version
Python 3.6.9
$ python3 -m doctest leak.py -v
[...]
3 passed and 0 Failed.
Test passed.
$ python3 -m unittest leak
/tmp/fileleak/leak.py:1: ResourceWarning: unclosed file <_io.TextIOWrapper name='test-file' mode='r' encoding='UTF-8'>
def hello(f):
/usr/lib/python3.6/doctest.py:2175: ResourceWarning: unclosed file <_io.TextIOWrapper name='test-file' mode='w' encoding='UTF-8'>
test.globs.clear()
.
----------------------------------------------------------------------
Ran 1 test in 0.003s
OK
有几种方法可以在 doctests 中清理它,但它们都增加了复杂性,会分散文档中的注意力。这包括使用 a.close()
对 with open("test-file") as a:
的显式调用(它还将测试的输出推送到 with
块下方,或者使用 `warnings.simplefilter("ignore") 直接丢弃警告。>
如何让 doctest 在 unittest
下运行以抑制 ResourceWarning()
像 doctest
那样?
解决方法
doctest
没有抑制这些警告。 unittest
是
启用它们。我们可能希望 unittest
为我们更多地启用它们
传统的单元测试,所以我们不想全局抑制这些。
我已经在使用 load_tests
将 doctest 添加到 unittest
,所以我们有
放置它的好地方。我们不能直接调用 warnings.filterwarnings()
在 load_tests
中,因为在我们的测试运行之前过滤器已重置。我们可以使用
doctest.DocTestSuite
的 setUp
参数提供一个函数来为我们完成工作。
def load_tests(loader,tests,ignore):
import doctest
import warnings
def setup(doc_test_obj):
for module in (__name__,'doctest'):
warnings.filterwarnings("ignore",message= r'unclosed file <_io.TextIOWrapper',category=ResourceWarning,module=module+"$")
tests.addTests(doctest.DocTestSuite(setUp=setup))
return tests
在我们创建的对象可能被破坏的任何地方,我们都需要过滤器
ResourceWarning
生成。这包括我们自己的模块 (__name__
),但它
还包括 doctest
因为一些全局变量直到
DocTestCase.tearDown
。
通过仔细指定按类别、消息和模块过滤的内容,这 应该限制抑制设计警告的风险,但并非没有风险。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。