如何在unittest下运行的doctest中抑制ResourceWarning()s

问题描述 投票:0回答:1

我的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
那样?

python python-unittest suppress-warnings doctest
1个回答
1
投票

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

通过仔细指定按类别、消息和模块过滤的内容,这 应该限制抑制设计警告的风险,但这并非没有风险。

© www.soinside.com 2019 - 2024. All rights reserved.