将(逐步)`DeprecationWarnings` 转变为 Python 中的致命错误
Turn (progressively) `DeprecationWarnings` into fatal errors in Python
我们的测试套件有很多 DeprecationWarnings
来自我们自己的代码。我的团队一直在不修复(或检查警告)受影响的测试的情况下弃用某些东西。我认为解决此问题的最佳方法是在测试上下文中 运行 时将这些警告转换为异常或测试失败。这样,团队不会在不重新调整受影响的测试的情况下引入 DeprecationWarning
s。
更重要的是,如果这种转换可以是渐进的(我们有很多测试需要开始一项一项地修复),那就太好了。我可以不时减少的某种白名单。
这是当前情况:
import warnings
class Addition:
def __init__(self, int1, int2):
self.int1 = int1
self.int2 = int2
def get_result(self):
warnings.warn("The method get_result() is being deprecated. Use result() instead.",
DeprecationWarning, 2)
return self.result()
def result(self):
return self.int1 + self.int2
from unittest import TestCase
from addition import Addition
class CustomTestCase(TestCase):
# ...
pass
class TestResultOperations(CustomTestCase):
def test_addition(self):
addition = Addition(2, 3)
self.assertEqual(addition.get_result(), 5)
如果有帮助,我们正在 运行 这些毒物测试。
没有完整的答案,但有一些提示:
我不知道如何逐步做到这一点。
我通常不会将所有警告都变成异常,因为第 3 方库中的警告也会导致测试失败。
不过,您可以在 tox
的命令部分为测试命令添加前缀。然后,带有非零 return 代码的命令也可以 运行 并显示错误,而不会使完整的 tox
运行 失败。
我很确定您可以使用 https://docs.python.org/3/using/cmdline.html#envvar-PYTHONWARNINGS 将警告变成错误,但我必须查一下。我目前在移动。
更新
正如您提到的,您使用 pytest
作为测试 运行ner...
[testenv:businessasusual]
commands = pytest <your-tests> # works as usual
[testenv:deprecations]
commands = - pytest -W error::DeprecationWarning <your-tests> # works
...其中
- 前导破折号(包括 space!!)使得 tox 运行 作为一个整体不会失败,但仍然会显示失败!!
- "-W error::DeprecationWarning" 把警告变成错误
那么您可以始终 运行 两者,或者仅通过 -e
中的一个。
这最终意味着,显示了现在的测试错误,但不要破坏 tox
运行。
这是我最终的做法:
class CustomTestCase(TestCase):
@classmethod
def setUpClass(cls):
allow_DeprecationWarning_modules = [
"...", # This is the allowlist, from where I will
"...", # progressively start removing modules that
"...", # use deprecated calls
]
warnings.filterwarnings("error", category=DeprecationWarning)
for mod in allow_DeprecationWarning_modules:
warnings.filterwarnings("default", category=DeprecationWarning, module=mod)
方法 setUpClass
在开始测试之前运行一次。在那里,我将操作 "error"
设置为 DeprecationWarning
警告类别,并附加“例外”以作为 "default"
运行。请注意,这是与测试运行器无关的。
我们的测试套件有很多 DeprecationWarnings
来自我们自己的代码。我的团队一直在不修复(或检查警告)受影响的测试的情况下弃用某些东西。我认为解决此问题的最佳方法是在测试上下文中 运行 时将这些警告转换为异常或测试失败。这样,团队不会在不重新调整受影响的测试的情况下引入 DeprecationWarning
s。
更重要的是,如果这种转换可以是渐进的(我们有很多测试需要开始一项一项地修复),那就太好了。我可以不时减少的某种白名单。
这是当前情况:
import warnings
class Addition:
def __init__(self, int1, int2):
self.int1 = int1
self.int2 = int2
def get_result(self):
warnings.warn("The method get_result() is being deprecated. Use result() instead.",
DeprecationWarning, 2)
return self.result()
def result(self):
return self.int1 + self.int2
from unittest import TestCase
from addition import Addition
class CustomTestCase(TestCase):
# ...
pass
class TestResultOperations(CustomTestCase):
def test_addition(self):
addition = Addition(2, 3)
self.assertEqual(addition.get_result(), 5)
如果有帮助,我们正在 运行 这些毒物测试。
没有完整的答案,但有一些提示:
我不知道如何逐步做到这一点。
我通常不会将所有警告都变成异常,因为第 3 方库中的警告也会导致测试失败。
不过,您可以在 tox
的命令部分为测试命令添加前缀。然后,带有非零 return 代码的命令也可以 运行 并显示错误,而不会使完整的 tox
运行 失败。
我很确定您可以使用 https://docs.python.org/3/using/cmdline.html#envvar-PYTHONWARNINGS 将警告变成错误,但我必须查一下。我目前在移动。
更新
正如您提到的,您使用 pytest
作为测试 运行ner...
[testenv:businessasusual]
commands = pytest <your-tests> # works as usual
[testenv:deprecations]
commands = - pytest -W error::DeprecationWarning <your-tests> # works
...其中
- 前导破折号(包括 space!!)使得 tox 运行 作为一个整体不会失败,但仍然会显示失败!!
- "-W error::DeprecationWarning" 把警告变成错误
那么您可以始终 运行 两者,或者仅通过 -e
中的一个。
这最终意味着,显示了现在的测试错误,但不要破坏 tox
运行。
这是我最终的做法:
class CustomTestCase(TestCase):
@classmethod
def setUpClass(cls):
allow_DeprecationWarning_modules = [
"...", # This is the allowlist, from where I will
"...", # progressively start removing modules that
"...", # use deprecated calls
]
warnings.filterwarnings("error", category=DeprecationWarning)
for mod in allow_DeprecationWarning_modules:
warnings.filterwarnings("default", category=DeprecationWarning, module=mod)
方法 setUpClass
在开始测试之前运行一次。在那里,我将操作 "error"
设置为 DeprecationWarning
警告类别,并附加“例外”以作为 "default"
运行。请注意,这是与测试运行器无关的。