有没有办法强制Python 3 unittest失败,而不是简单地向stderr发出警告,如果它导致任何ResourceWarning?
我尝试过以下方法:
import warnings
warnings.simplefilter(action='error', category=ResourceWarning)
Run Code Online (Sandbox Code Playgroud)
这导致unittest的输出:
my_test (__main__.MyTest) ... Exception ignored in: <socket.socket fd=9, family=AddressFamily.AF_INET, type=SocketType.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 54065), raddr=('127.0.0.1', 27017)>
ResourceWarning: unclosed <socket.socket fd=9, family=AddressFamily.AF_INET, type=SocketType.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 54065), raddr=('127.0.0.1', 27017)>
ok
----------------------------------------------------------------------
Ran 1 test in 0.110s
Run Code Online (Sandbox Code Playgroud)
请注意"忽略异常"消息.我宁愿测试失败,而不是要求我阅读其输出,寻找ResourceWarnings.
如果ResourceWarning由with catch_warning()语句中的代码生成,则单元测试失败:
#!/usr/bin/env python3
import gc
import socket
import unittest
import warnings
class Test(unittest.TestCase):
def test_resource_warning(self):
s = socket.socket()
####s.close() #XXX uncomment to pass the test
# generate resource warning when s is deleted
with warnings.catch_warnings(record=True) as w:
warnings.resetwarnings() # clear all filters
warnings.simplefilter('ignore') # ignore all
warnings.simplefilter('always', ResourceWarning) # add filter
del s # remove reference
gc.collect() # run garbage collection (for pypy3)
self.assertFalse(w and str(w[-1])) # test fails if there
# are warnings
if __name__=="__main__":
unittest.main()
Run Code Online (Sandbox Code Playgroud)
不幸的是,这似乎不可能。“在忽略异常:”消息由CPython的函数产生PyErr_WriteUnraisable在Python/errors.c。该函数之前的评论指出:
/* Call when an exception has occurred but there is no way for Python
to handle it. Examples: exception in __del__ or during GC. */
Run Code Online (Sandbox Code Playgroud)
该ResourceWarning确实正在垃圾收集过程中产生的,因为它并没有以此来提高在这一点上异常的Python打印消息。这与核心 CPython 实现有关,并且 unittest 无法覆盖它。
更新:虽然以上是正确的技术分析,但还有另一种方法可以实际解决 OP 的问题。有关更多详细信息,请参阅JF Sebastian的回答。
| 归档时间: |
|
| 查看次数: |
1170 次 |
| 最近记录: |