Skip to content

Commit 27a8dd6

Browse files
committed
14.3小节完成
1 parent 97e42c0 commit 27a8dd6

File tree

1 file changed

+75
-69
lines changed

1 file changed

+75
-69
lines changed

source/c14/p03_testing_for_exceptional_conditions_in_unit_tests.rst

Lines changed: 75 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -5,91 +5,97 @@
55
----------
66
问题
77
----------
8-
You want to write a unit test that cleanly tests if an exception is raised.
8+
你想写个测试用例来准确的判断某个异常是否被抛出。
99

1010
|
1111
1212
----------
1313
解决方案
1414
----------
15-
To test for exceptions, use the assertRaises() method. For example, if you want to test
16-
that a function raised a ValueError exception, use this code:
15+
对于异常的测试可使用 ``assertRaises()`` 方法。
16+
例如,如果你想测试某个函数抛出了 ``ValueError`` 异常,像下面这样写:
1717

18-
import unittest
18+
.. code-block:: python
1919
20-
# A simple function to illustrate
21-
def parse_int(s):
22-
return int(s)
20+
import unittest
2321
24-
class TestConversion(unittest.TestCase):
25-
def test_bad_int(self):
26-
self.assertRaises(ValueError, parse_int, 'N/A')
22+
# A simple function to illustrate
23+
def parse_int(s):
24+
return int(s)
2725
28-
If you need to test the exception’s value in some way, then a different approach is needed.
29-
For example:
26+
class TestConversion(unittest.TestCase):
27+
def test_bad_int(self):
28+
self.assertRaises(ValueError, parse_int, 'N/A')
3029
31-
import errno
30+
如果你想测试异常的具体值,需要用到另外一种方法:
3231

33-
class TestIO(unittest.TestCase):
34-
def test_file_not_found(self):
35-
try:
36-
f = open('/file/not/found')
37-
except IOError as e:
38-
self.assertEqual(e.errno, errno.ENOENT)
32+
.. code-block:: python
3933
40-
else:
41-
self.fail('IOError not raised')
34+
import errno
35+
36+
class TestIO(unittest.TestCase):
37+
def test_file_not_found(self):
38+
try:
39+
f = open('/file/not/found')
40+
except IOError as e:
41+
self.assertEqual(e.errno, errno.ENOENT)
42+
43+
else:
44+
self.fail('IOError not raised')
4245
4346
|
4447
4548
----------
4649
讨论
4750
----------
48-
The assertRaises() method provides a convenient way to test for the presence of an
49-
exception. A common pitfall is to write tests that manually try to do things with excep‐
50-
tions on their own. For instance:
51-
52-
class TestConversion(unittest.TestCase):
53-
def test_bad_int(self):
54-
try:
55-
r = parse_int('N/A')
56-
except ValueError as e:
57-
self.assertEqual(type(e), ValueError)
58-
59-
The problem with such approaches is that it is easy to forget about corner cases, such
60-
as that when no exception is raised at all. To do that, you need to add an extra check for
61-
that situation, as shown here:
62-
63-
class TestConversion(unittest.TestCase):
64-
def test_bad_int(self):
65-
try:
66-
r = parse_int('N/A')
67-
except ValueError as e:
68-
self.assertEqual(type(e), ValueError)
69-
else:
70-
self.fail('ValueError not raised')
71-
72-
The assertRaises() method simply takes care of these details, so you should prefer to
73-
use it.
74-
The one limitation of assertRaises() is that it doesn’t provide a means for testing the
75-
value of the exception object that’s created. To do that, you have to manually test it, as
76-
shown. Somewhere in between these two extremes, you might consider using the as
77-
sertRaisesRegex() method, which allows you to test for an exception and perform a
78-
regular expression match against the exception’s string representation at the same time.
79-
For example:
80-
81-
class TestConversion(unittest.TestCase):
82-
def test_bad_int(self):
83-
self.assertRaisesRegex(ValueError, 'invalid literal .*',
84-
parse_int, 'N/A')
85-
86-
A little-known fact about assertRaises() and assertRaisesRegex() is that they can
87-
also be used as context managers:
88-
89-
class TestConversion(unittest.TestCase):
90-
def test_bad_int(self):
91-
with self.assertRaisesRegex(ValueError, 'invalid literal .*'):
92-
r = parse_int('N/A')
93-
94-
This form can be useful if your test involves multiple steps (e.g., setup) besides that of
95-
simply executing a callable.
51+
``assertRaises()`` 方法为测试异常存在性提供了一个简便方法。
52+
一个常见的陷阱是手动去进行异常检测。比如:
53+
54+
.. code-block:: python
55+
56+
class TestConversion(unittest.TestCase):
57+
def test_bad_int(self):
58+
try:
59+
r = parse_int('N/A')
60+
except ValueError as e:
61+
self.assertEqual(type(e), ValueError)
62+
63+
这种方法的问题在于它很容易遗漏其他情况,比如没有任何异常抛出的时候。
64+
那么你还得需要增加另外的检测过程,如下面这样:
65+
66+
.. code-block:: python
67+
68+
class TestConversion(unittest.TestCase):
69+
def test_bad_int(self):
70+
try:
71+
r = parse_int('N/A')
72+
except ValueError as e:
73+
self.assertEqual(type(e), ValueError)
74+
else:
75+
self.fail('ValueError not raised')
76+
77+
``assertRaises()`` 方法会处理所有细节,因此你应该使用它。
78+
79+
``assertRaises()`` 的一个缺点是它测不了异常具体的值是多少。
80+
为了测试异常值,可以使用 ``assertRaisesRegex()`` 方法,
81+
它可同时测试异常的存在以及通过正则式匹配异常的字符串表示。例如:
82+
83+
.. code-block:: python
84+
85+
class TestConversion(unittest.TestCase):
86+
def test_bad_int(self):
87+
self.assertRaisesRegex(ValueError, 'invalid literal .*',
88+
parse_int, 'N/A')
89+
90+
``assertRaises()`` 和 ``assertRaisesRegex()``
91+
还有一个容易忽略的地方就是它们还能被当做上下文管理器使用:
92+
93+
.. code-block:: python
94+
95+
class TestConversion(unittest.TestCase):
96+
def test_bad_int(self):
97+
with self.assertRaisesRegex(ValueError, 'invalid literal .*'):
98+
r = parse_int('N/A')
99+
100+
但你的测试涉及到多个执行步骤的时候这种方法就很有用了。
101+

0 commit comments

Comments
 (0)