我的Python doctests 打开一些永远不会关闭的文件。这不会造成任何问题;当对象被销毁时它们会自动关闭,并且添加逻辑以确保它们明确关闭会使我的文档不必要地复杂化。
unittest
内部运行时,它们开始发出 ResourceWarning()
,为我的输出添加无用的噪音。
例如,给定leak.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
使用Python 3.6.9在doctest和unittest下运行它会生成:
$ 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
有几种方法可以在文档测试中清理这个问题,但它们都会增加复杂性,从而分散文档的注意力。这包括使用
a.close()
显式调用 with open("test-file") as a:
(这还将测试的输出推到 with
块下方,或者使用 warnings.simplefilter("ignore")
彻底丢弃警告。
如何让文档测试在
unittest
下运行以抑制 ResourceWarning()
,就像 doctest
那样?
doctest
是不是抑制这些警告。 unittest
是
使他们能够。我们可能想要unittest
让他们为我们提供更多
传统的单元测试,所以我们不想在全球范围内压制这些。
load_tests
将文档测试添加到 unittest
,所以我们有
一个放置它的好地方。我们不能直接调用 warnings.filterwarnings()
在 load_tests
中,因为在我们的测试运行之前过滤器被重置。我们可以使用
setUp
参数 doctest.DocTestSuite
提供一个函数来为我们完成这项工作。
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
。
通过仔细指定按类别、消息和模块过滤的内容,这 应该限制抑制设计警告的风险,但这并非没有风险。