即使在日志中看到提升,异常提升也不会反映在测试用例中

时间:2014-11-22 02:28:32

标签: python regex exception testing exception-handling

我在Python中练习TDD,并在测试是否引发异常时遇到了问题。

以下test_phonebook.py test_add_empty_name_raises_exception失败。

import unittest
import phonebook


class Test(unittest.TestCase):

    def test_add_empty_name_raises_exception(self):
        self.assertRaises(ValueError, phonebook.add, "", "1111111111")

if __name__ == "__main__":
    # import sys;sys.argv = ['', 'Test.testName']
    unittest.main()

以下是我的phonebook.py方法add,它将数据添加到词典中。

import re

_phonebook = {}
file_name = "phonebook.txt"


def is_valid_name(name):
    return re.search(r"([A-Z][a-z]*)([\\s\\\'-][A-Z][a-z]*)*", name) is not None


def is_valid_number(number):
    return re.search(r"\+?[\d ]+$", number) is not None


def add(name, number):
    try:
        if is_valid_name(name) and is_valid_number(number):
            _phonebook[name] = number
        else:
            raise ValueError("Invalid arguments.", name, number)
    except ValueError as err:
        print err.args


if __name__ == '__main__':
    pass

我的问题是,即使在控制台日志中看到ValueError方法中出现了add,测试也会失败。

Finding files... done.
Importing test modules ... done.

('Invalid arguments.', '', '1111111111')
======================================================================
FAIL: test_add_empty_name_raises_exception (path.to.phonebook.test_phonebook.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "path\to\phonebook\test_phonebook.py", line 13, in test_add_empty_name_raises_exception
    self.assertRaises(ValueError, phonebook.add, "", "1111111111")
AssertionError: ValueError not raised

----------------------------------------------------------------------
Ran 1 test in 0.002s

我该如何解决这个问题?我有遗忘的东西吗?

我也尝试在Python 2.7中使用新格式处理测试中的异常,但它仍然没有引起ValueError的提升。

def test_add_empty_name_raises_exception(self):
    with self.assertRaises(ValueError):
        self.phonebook.add("", "1111111111)

我还将测试用例的形式更改为使用lambdas,但仍然没有更改。

def test_add_empty_name_raises_exception(self):
    self.assertRaises(ValueError, lambda: phonebook.add("", "1111111111"))

我还清理了我的目录并重新启动了Eclipse Luna,问题仍然存在。

可能的解决方案

我正在阅读8.Errors and Exceptions文档并进入" Raising Exceptions"部分说明:

If you need to determine whether an exception was raised but don’t intend to handle it, 
a simpler form of the raise statement allows you to re-raise the exception:

我将此添加到现有的add方法中:

def add(name, number):
    try:
        if is_valid_name(name) and is_valid_number(number):
            _phonebook[name] = number
            print "Added %s:\t%s" % (name, number)
        else:
            raise ValueError("Invalid arguments.", name, number)
    except ValueError as err:
        print err.args
        raise

导致测试用例通过。

这是正确的方法吗?要在raise区块再次致电except吗?

1 个答案:

答案 0 :(得分:2)

当您捕获异常(在except ValueError as err:块中)时,会阻止它继续备份调用堆栈以最终终止程序。从本质上讲,你说'#34;我知道如何处理这个问题,所以不需要恐慌其他人。"

重新引发异常是正确的做法,如果您发现了异常,但没有这样做以实际修复任何事情,例如,记录它发生的事情。但是,通常情况下,人们会捕获异常以便纠正它。

在您的情况下,您自己提出异常后几乎立即捕获异常。为什么不将您的日志记录语句放在与else相同的raise块中?根本不需要try: ... except:缩进。

def add(name, number):
    if is_valid_name(name) and is_valid_number(number):
        _phonebook[name] = number
        print "Added %s:\t%s" % (name, number)
    else:
        print "Invalid arguments.", name, number
        raise ValueError("Invalid arguments.", name, number)
    return