Python 3.2为未封闭的系统资源(网络套接字,文件)引入了ResourceWarning
:
虽然代码在生产中运行干净,但由于使用了发生警告的第三方库,因此在运行单元测试时会收到很多关注警告。我可以修复库,但另一方面,在测试运行期间忽略它会简单得多。
block_io-python/block_io/__init__.py:182: ResourceWarning: unclosed <ssl.SSLSocket fd=11, family=AddressFamily.AF_INET, type=SocketType.SOCK_STREAM, proto=6, laddr=('x', 58395), raddr=('x, 443)>
禁用这些警告的方法是什么?我尝试了以下但没有效果:
warnings.filterwarnings("ignore", category=ResourceWarning)
(在单元测试导入时间内运行)。
答案 0 :(得分:26)
我找到了罪魁祸首。您说您在导入时设置过滤器。但是,自Python 3.2以来,unittest模块已更新为将警告过滤器设置为默认值。见Section 29.5.5。基本上,unittest
会在完成导入模块后覆盖警告过滤器首选项。
例如。
my_tests.py
import socket
import unittest
import warnings
warnings.simplefilter("ignore", ResourceWarning)
def abusesocket():
s = socket.socket()
s.connect(("www.google.com", 80))
class Test(unittest.TestCase):
def test1(self):
print("test1")
abusesocket()
print("module import warning filter nixed")
def test2(self):
print("test2")
warnings.simplefilter("ignore", ResourceWarning)
abusesocket()
print("higher warning filter okay")
提供以下输出
$ python3 -m unittest my_tests.py
test1
/home/user/my_tests.py:15: ResourceWarning: unclosed <socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketType.SOCK_STREAM, proto=0, laddr=('x.x.x.x', 52332), raddr=('31.55.166.217', 80)>
abusesocket()
module import warning filter nixed
.test2
higher warning filter okay
.
----------------------------------------------------------------------
Ran 2 tests in 0.347s
OK
unittest
似乎都会重置警告过滤器。因此,您将在每次测试开始时清除过滤器。可能最好使用装饰器来包装你的测试功能。
def ignore_warnings(test_func):
def do_test(self, *args, **kwargs):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ResourceWarning)
test_func(self, *args, **kwargs)
return do_test
class Test(unittest.TestCase):
@ignore_warnings
def test1(self):
abusesocket()
答案 1 :(得分:19)
unittest.main(警告= '忽略')
答案 2 :(得分:3)
我用它来在测试之前仅禁用ResourceWarning
警告,然后在以后重新启用它。
import unittest
import warnings
class MyTestCase(unittest.TestCase):
def setUp(self):
warnings.simplefilter("ignore", ResourceWarning)
def tearDown(self):
warnings.simplefilter("default", ResourceWarning)
答案 3 :(得分:1)
在类级别为所有方法设置一次似乎比作为实例级别setUp()重复进行更为有效:
@classmethod
def setUpClass(cls):
warnings.simplefilter("ignore")
答案 4 :(得分:0)
这个替代方法对我有用:
def setUp(self):
if not sys.warnoptions:
import warnings
warnings.simplefilter("ignore")