转载请注明原始出处:http://blog.csdn.net/a464057216/article/details/51889564
这篇博客详细介绍Python的unittest模块内部的类及方法的更多内容。
class unittest.TestCase(methodName='runTest')
这个类的实例表示一个测试用例,默认的methodName是runTest
,即最简单的测试用例类的定义只包含runTest
方法的定义。如果同时定义了runTest
方法和以test开头命名的方法,会忽略runTest
方法。如果要指定执行某些方法,可以这样:
suite = unittest.TestSuite()
suite.addTest(Test('test_al'))
unittest.TextTestRunner(verbosity=2).run(suite)
TestCase类中定义的方法分为三大类:测试执行;结果检查及错误上报;查询测试用例信息。
在执行每个测试用例之前被执行,任何异常(除了unittest.SkipTest
和AssertionError
异常以外)都会当做是error而不是failure,且会终止当前测试用例的执行。
执行了setUp()
方法后,不论测试用例执行是否成功,都执行tearDown()
方法。如果tearDown()的代码有异常(除了unittest.SkipTest
和AssertionError
异常以外),会多算一个error。
测试用例们被执行前、后执行的方法,定义时必须加上classmethod装饰符,比如:
import unittest
class MyTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
print 'set up class ran'
def setUp(self):
print 'set up test case ran'
def test_equal(self):
self.assertEqual(1, 1, '1 not equals 1')
def test_true(self):
self.assertTrue('LOO'.isupper(), 'LOO not upper')
def tearDown(self):
print 'tear down test case ran'
@classmethod
def tearDownClass(cls):
print 'tear down class ran'
测试结果如下:
$ python -m unittest unit
set up class ran
set up test case ran
tear down test case ran
.set up test case ran
tear down test case ran
.tear down class ran
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
在某个测试用例函数的定义中调用skipTest(reason)会忽略这个测试用例的执行,在setUp()方法中调用,会忽略所有测试用例的执行。其实skipTest(reason)函数抛出的就是unittest.SkipTest异常。
运行一个测试用例,将测试结果收集到result变量中,测试结果不返回给调用者。如果result参数的值为None,则测试结果在下面提到的defaultTestResult()方法的返回值中。比如:
import unittest
class Sample(unittest.TestCase):
def test_a(self):
assert 1 == 2, 'test print Errors'
print 'test_a'
if __name__ == '__main__':
r = unittest.TestResult()
Sample('test_a').run(result=r)
print r.__dict__
执行结果如下:
与run方法将测试结果存储到result变量中不同,debug方法运行测试用例将异常信息上报给调用者。
Method | Checks that |
---|---|
assertEqual(a, b) | a == b |
assertNotEqual(a, b) | a != b |
assertTrue(x) | bool(x) is True |
assertFalse(x) | bool(x) is False |
assertIs(a, b) | a is b |
assertIsNot(a, b) | a is not b |
assertIsNone(x) | x is None |
assertIsNotNone(x) | x is not None |
assertIn(a, b) | a in b |
assertNotIn(a, b) | a not in b |
assertIsInstance(a, b) | isinstance(a, b) |
assertNotIsInstance(a, b) | not isinstance(a, b) |
assertAlmostEqual(a, b) | round(a-b, 7) == 0 |
assertNotAlmostEqual(a, b) | round(a-b, 7) != 0 |
assertGreater(a, b) | a > b |
assertGreaterEqual(a, b) | a >= b |
assertLess(a, b) | a < b |
assertLessEqual(a, b) | a <= b |
assertRegexpMatches(s, r) | r.search(s) |
assertNotRegexpMatches(s, r) | not r.search(s) |
assertItemsEqual(a, b) | sorted(a) == sorted(b) and works with unhashable objs |
上面所有的方法都支持添加第三个字符串参数,用于出错时的信息展示。
assertIsInstance(a, b)和assertNotIsInstance(a, b)中的类型b,既可以是一个类型,也可以是类型组成的元组。
assertAlmostEqual(first, second, places=7, msg=None, delta=None)
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)
判断两个值是否约等于或者不约等于,places表示小数点后精确的位数。比如,如果精确到小数点后两位,1.112和1.113是相等的:
import unittest
class Test(unittest.TestCase):
def test_al(self):
self.assertAlmostEqual(1.111, 1.112, places=2)
如果精确到后3位,则是不相等的:
如果提供了delta参数,则不能同时提供places参数(这时比较两个变量的差值<=delta或者>delta)。
比较a和b的元素相同,且不忽略重复的元素,比如[2, 3, 1]与[3, 2, 1]是items equal的,但是[2, 2, 1]和[2, 1]不是item equal的。
如果有自定义的类,这个函数可以为自定义的类提供相等性检查方法,比如:
import unittest
class Mars(object):
def __init__(self):
self.value = 2
def change_to(self, value):
self.value = value
def get_value(self):
return self.value
def looFunc(first, second, msg=None):
if first.get_value() != second.get_value():
raise unittest.TestCase.failureException(msg)
class MarsTest(unittest.TestCase):
def __init__(self, methodName):
super(MarsTest, self).__init__(methodName)
self.addTypeEqualityFunc(Mars, looFunc)
def test_my(self):
a = Mars()
b = Mars()
b.change_to(6)
self.assertEqual(a, b, 'a not equal b')
Method | Checks that |
---|---|
assertRaises(exc, fun, *args, **kwds) | fun(*args, **kwds) raises exc |
assertRaisesRegexp(exc, r, fun, *args,**kwds) | fun(*args, **kwds) raises exc and the message matches regex r |
检查异常的方法是没有错误信息提示参数的。如果期望的异常有多个,也可以给exc参数一个多个异常组成的元组,比如:
import unittest, random
def raise_exec1():
raise Exception('mars')
def raise_exec2():
raise random.choice([NameError('[3] failed'), TypeError('[1]')])
class MyTestCase(unittest.TestCase):
def test_exec(self):
self.assertRaises(Exception, raise_exec1)
def test_exec2(self):
self.assertRaisesRegexp((NameError, TypeError), r'\[\d\]\w*', raise_exec2)
如果只提供exc参数也是可以的,这时返回一个上线文管理器,可以配合with语句把要调用的函数放在上线文管理器中调用,并且unittest将被调用函数返回的异常赋值给上下文管理器的返回值的exception属性,比如:
import unittest
class marsException(Exception):
error_code = 3
def raise_exec1():
raise marsException('mars')
class MyTestCase(unittest.TestCase):
def test_exec1(self):
with self.assertRaises(marsException) as cm:
raise_exec1()
self.assertEqual(cm.exception.error_code, 3,
'Error code error')
测试结果如下:
$ python -m unittest -v unit
test_exec1 (unit.MyTestCase) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
无条件声明一个测试用例失败,msg是失败信息。
是unittest.TestCase的属性,用来表示失败的异常,默认被赋值为AssertionError。
默认被赋值为False,如果赋值为True,可以在结果中包含更详细的diff信息。
默认长度80*8,用来控制diff显示的长度。
返回测试用例的个数,对于TestCase实例来说,这个返回值一直是1.
如果在run()方法中未提供result参数,该函数返回一个包含本用例测试结果的TestResult对象。
返回测试用例的编号,通常是如下格式:模块名.类名.函数名。可以用于测试结果的输出。
返回测试用例的描述,即函数的docstring,如果没有,返回None。可以用于测试结果输出中描述测试内容。
添加针对每个测试用例执行完tearDown()方法之后的清理方法,添加进去的函数按照后进先出(LIFO)的顺序执行,当然,如果setUp()方法执行失败,那么不会执行tearDown()方法,自然也不会执行addCleanup()里添加的函数。
无条件强制调用addCleanup()添加的函数,适用于setUp()方法执行失败但是需要执行清理函数的场景,或者希望在tearDown()方法之前执行这些清理函数。
class unittest.TestSuite(tests=())
TestSuite类用于将测试用例分组,比如实际工作中需要将测试用例按照优先级分类。tests参数是一个可迭代的对象,每个对象可以是测试用例,也可以是测试套,比如:
import unittest
class A(unittest.TestCase):
def test_a(self):
print 'test_a'
class B(unittest.TestCase):
def test_b(self):
print 'test_b'
def test_c(self):
print 'test_c'
if __name__ == '__main__':
suite1 = unittest.TestSuite(tests=[B('test_c'), A('test_a')])
suite = unittest.TestSuite(tests=(suite1, B('test_b')))
unittest.TextTestRunner(verbosity=2).run(suite)
添加测试用例,test参数可以是一个TestCase实例或者TestSuite实例。
tests参数是一个由测试用例或测试套组成的可迭代对象。
运行测试套中包含的用例,将结果保存到result参数对应的TestResult对象中,比如:
import unittest
class A(unittest.TestCase):
def test_a(self):
print 'test_a'
class B(unittest.TestCase):
def test_b(self):
print 'test_b'
def test_c(self):
print 'test_c'
if __name__ == '__main__':
suite1 = unittest.TestSuite(tests=[B('test_c'), A('test_a')])
suite = unittest.TestSuite()
suite.addTest(suite1)
r = unittest.TestResult()
suite.run(r)
print r.__dict__
与TestCase中的debug()中的功能相同,运行测试用例,如果有异常,将异常上报给调用者。
返回测试套中测试用例的数量,比如:
import unittest
class A(unittest.TestCase):
def test_a(self):
print 'test_a'
class B(unittest.TestCase):
def test_b(self):
print 'test_b'
def test_c(self):
print 'test_c'
if __name__ == '__main__':
suite1 = unittest.TestSuite(tests=[B('test_c'), A('test_a')])
suite = unittest.TestSuite(tests=(suite1, B('test_b')))
print suite.countTestCases()
运行结果为:3。
如果觉得我的文章对您有帮助,欢迎关注我(CSDN:Mars Loo的博客)或者为这篇文章点赞,谢谢!