[英]How to make assertRaises() print the passed *args, **kwargs in Python 2.7?
I'm using assertRaises
in a loop like this: 我在这样的循环中使用
assertRaises
:
for i in ['a', 'b', 'c']:
self.assertRaises(ValidationError, my_method, i)
And the problem is that whenever test fails, the output looks like this: 问题是每当测试失败时,输出将如下所示:
File "/bla/test.py", line 4, in test_assertion
my_method(i)
AssertionError: ValidationError not raised
How to make it print out the value of i
when test fails? 测试失败时如何打印出
i
的值? Like this: 像这样:
File "/bla/test.py", line 4, in test_assertion
my_method('b')
AssertionError: ValidationError not raised
This is the ideal situation for the subTests
context manager. 这是
subTests
上下文管理器的理想情况。 However, this is only available in python 3. I think the best solution would be to create your own version of subTests
. 但是,这仅在python 3中可用。我认为最好的解决方案是创建自己的
subTests
版本。 The benefits being it's easy to setup a basic mimicry of subTests
, and if subTests
is ever back ported to python 2 then it will be easy to switch. 好处是可以很容易地设置
subTests
的基本模拟,并且如果将subTests
重新移植到python 2,则将很容易切换。
import unittest
import sys
from contextlib import contextmanager
class TestCaseWithSubTests(unittest.TestCase):
@contextmanager
def subTest(self, **kwargs):
try:
yield None
except:
exc_class, exc, tb = sys.exc_info()
kwargs_desc = ", ".join("{}={!r}".format(k, v) for k, v in kwargs.items())
new_exc = exc_class("with {}: {}".format(kwargs_desc, exc))
raise exc_class, new_exc, tb.tb_next
class MyTest(TestCaseWithSubTests):
def test_with_assertion_error(self):
for i in [0, 1]:
with self.subTest(i=i), self.assertRaises(ZeroDivisionError):
1 / i
def test_with_value_error(self):
def f(i):
raise ValueError
for i in [0, 1]:
with self.subTest(i=i), self.assertRaises(ZeroDivisionError):
f(i)
if __name__ == "__main__":
unittest.main()
Which produces the following output: 产生以下输出:
FE
======================================================================
ERROR: test_with_value_error (__main__.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\dunes\py2sub_tests.py", line 30, in test_with_value_error
f(i)
File "C:\Python27\lib\contextlib.py", line 35, in __exit__
self.gen.throw(type, value, traceback)
File "C:\Users\dunes\py2sub_tests.py", line 30, in test_with_value_error
f(i)
File "C:\Users\dunes\py2sub_tests.py", line 26, in f
raise ValueError
ValueError: with i=0:
======================================================================
FAIL: test_with_assertion_error (__main__.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\dunes\py2sub_tests.py", line 22, in test_with_assertion_error
1 / i
File "C:\Python27\lib\contextlib.py", line 35, in __exit__
self.gen.throw(type, value, traceback)
File "C:\Users\dunes\py2sub_tests.py", line 22, in test_with_assertion_error
1 / i
AssertionError: with i=1: ZeroDivisionError not raised
----------------------------------------------------------------------
Ran 2 tests in 0.006s
FAILED (failures=1, errors=1)
One solution is to use assertRaises()
as a context manager. 一种解决方案是使用
assertRaises()
作为上下文管理器。
with self.assertRaises(ValidationError):
my_method(i)
print("Failed when i was",i)
The print statement will only execute when the my_method()
line passes successfully, so it will appear as the output when your test fails. 仅当
my_method()
行成功通过时,print语句才会执行,因此当测试失败时,它将显示为输出。 Bit of a hack, but it works (unless my_method()
throws some error that is not a ValidationError
). 有点
my_method()
,但确实有效(除非my_method()
抛出不是ValidationError
错误)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.