在Python中如何正确测试变量是否为非空字符串(unittest)?
也许这个问题很简单,但我还在努力熟悉Python中的单元测试,所以请多多包涵。:-) 在尝试写一些自己的测试时,我遇到了一个问题。假设有一个函数是用来处理非空字符串的:
class BadInputError(Exception): pass
class FooBar(object):
def take_a_string_and_do_something(param):
if param == '':
raise BadInputError('param should not be an empty string')
if param is None:
raise BadInputError('param should not be None')
if not isinstance(param, basestring):
raise BadInputError('param must be of type string)
# process nonempty string
我首先想通过单元测试确保param
只是一条非空字符串。所以我这样写了我的测试用例。
class TestFooBar(unittest.TestCase):
def test_take_a_string_and_do_something(self):
foo = FooBar()
self.failUnlessRaises(BadInputError, foo.take_a_string_and_do_something, '')
self.failUnlessRaises(BadInputError, foo.take_a_string_and_do_something, None)
self.failUnlessRaises(BadInputError, foo.take_a_string_and_do_something, 234)
这样做可以吗,还是我犯了个大错?你的反馈对我很重要!
2 个回答
3
如果它看起来像只鸭子,那就是只鸭子。别太担心类型的问题。只要尽量使用参数。如果你真的需要确认这个参数看起来没问题,你可以这样做:
if not hasattr(param, 'replace'):
raise ValueError('I cant work with param')
...或者,如果你真的很在意这个参数必须是某种东西(而不是空的):
if not param:
raise ValueError('param should not be empty')
嘎嘎。
3
这样做可以吗,还是我犯了个大错?
可以,也不可以。
这是一个写单元测试的好例子。
但是,这种情况在你的代码中本来就不应该存在。
class FooBar(object):
def take_a_string_and_do_something(self, param):
# process nonempty string
# If they couldn't provide a non-empty string, they get an exception.
你仍然可以这样测试。
class TestFooBar(unittest.TestCase):
def setUp( self ):
self.foo= FooBar()
def test_zero_length_should_fail(self):
self.failUnlessRaises(IndexError, foo.take_a_string_and_do_something, '')
def test_none_should_fail(self):
self.failUnlessRaises(TypeError, foo.take_a_string_and_do_something, None)
def test_non_string_should_fail(self):
self.failUnlessRaises(TypeError, foo.take_a_string_and_do_something, 234)
注意,这样做简单多了,而且更可靠,因为你不需要重复Python内部复杂的错误检查。