15.1. Handling bugs
-
Despite your best efforts to write comprehensive unit tests, bugs happen. What do I mean by "bug"? A bug is a test case you haven't written yet.
[pope 译]
尽管你做了最完成的单元测试,但bugs还是出现了。那bug又意味着什么呢?一个bug就是一个你还没有写的测试用例
+ - Example 15.1. The bug
-
>>> import roman5
>>> roman5.fromRoman("") ------------------------------1
0
-
1.
Remember in the previous section when you kept seeing that an empty string would match the regular expression you were using to check for valid Roman numerals? Well, it turns out that this is still true for the final version of the regular expression. And that's a bug; you want an empty string to raise an InvalidRomanNumeralError exception just like any other sequence of characters that don't represent a valid Roman numeral.
[pope译]
可记的前章曾见空串符合罗马数字的检查?是,此版本正则检查出的问题显示为真。是个bug,你本意空串为假 抛出 InvalidRomanNumeralError异常 ,就像其他非罗马数字列表。
[pope 译]
重现此bug后,修复前,你当写此失效的测试用例,来记述{illustrating}此bug
-
1.
-
class FromRomanBadInput(unittest.TestCase):
# previous test cases omitted for clarity (they haven't changed)
def testBlank(self):
"""fromRoman should fail with blank string"""
self.assertRaises(roman.InvalidRomanNumeralError, roman.fromRoman, "") --------------------1
-
1
Pretty simple stuff here. Call fromRoman with an empty string and make sure it raises an InvalidRomanNumeralError exception. The hard part was finding the bug; now that you know about it, testing for it is the easy part.
[pope译]
此处颇{pretty}简单.用空串调fromRoman,且确定此当抛InvalidRomanNumeralError异常。难出是发现此bug;现在君当知testing才是简单的部分而已。
-
1
[pope译]
因code有bug,且现在有此bug的测试用例,此用例执行失败如下:
-
Example 15.3. Output of romantest61.py against roman61.py
fromRoman should only accept uppercase input ... ok
toRoman should always return uppercase ... ok
fromRoman should fail with blank string ... FAIL
fromRoman should fail with malformed antecedents ... ok
fromRoman should fail with repeated pairs of numerals ... ok
fromRoman should fail with too many repeated numerals ... ok
fromRoman should give known result with known input ... ok
toRoman should give known result with known input ... ok
fromRoman(toRoman(n))==n for all n ... ok
toRoman should fail with non−integer input ... ok
toRoman should fail with negative input ... ok
toRoman should fail with large input ... ok
toRoman should fail with 0 input ... ok
======================================================================
FAIL: fromRoman should fail with blank string
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
Traceback (most recent call last):
File "C:\docbook\dip\py\roman\stage6\romantest61.py", line 137, in testBlank
self.assertRaises(roman61.InvalidRomanNumeralError, roman61.fromRoman, "")
File "c:\python21\lib\unittest.py", line 266, in failUnlessRaises
raise self.failureException, excName
AssertionError: InvalidRomanNumeralError
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
Ran 13 tests in 2.864s
FAILED (failures=1)
[pope 译]
现在来修复此bug
+ - Example 15.4. Fixing the bug (roman62.py)
-
This file is available in py/roman/stage6/ in the examples directory
[pope 译]
此文py/roman/stage6/ 实例文件中
def fromRoman(s):
"""convert Roman numeral to integer"""
if not s: ------------------------------------------------------------------------------1
raise InvalidRomanNumeralError, 'Input can not be blank'
if not re.search(romanNumeralPattern, s):
raise InvalidRomanNumeralError, 'Invalid Roman numeral: %s' % s
result = 0
index = 0
for numeral, integer in romanNumeralMap:
while s[index:index+len(numeral)] == numeral:
result += integer
index += len(numeral)
return result
-
1
Only two lines of code are required: an explicit check for an empty string, and a raise statement.
[pope译]
只需两行代码:明确查空串,抛异常声明
-
1
-
fromRoman should only accept uppercase input ... ok
toRoman should always return uppercase ... ok
fromRoman should fail with blank string ... ok --------------------------------------------------------1
fromRoman should fail with malformed antecedents ... ok
fromRoman should fail with repeated pairs of numerals ... ok
fromRoman should fail with too many repeated numerals ... ok
fromRoman should give known result with known input ... ok
toRoman should give known result with known input ... ok
fromRoman(toRoman(n))==n for all n ... ok
toRoman should fail with non−integer input ... ok
toRoman should fail with negative input ... ok
toRoman should fail with large input ... ok
toRoman should fail with 0 input ... ok
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
Ran 13 tests in 2.834s
OK --------------------------------------------------------2
-
1
The blank string test case now passes, so the bug is fixed
[pope译]
空串测试用例通过,此bug修复
2.
All the other test cases still pass, which means that this bug fix didn't break anything else. Stop coding
[pope译]
全部测试用例通过,这意味修复bug未引入其他。停止编程了
-
1
-
>>> import roman5
没有评论:
发表评论