一、摘要
单元测试里很重要的一个部分就是断言,unittest为我们提供了很多断言方法,断言方法分为三类,一种是用来断言被测试的方法的,另一种是测试是否抛正确异常的,第三种是用来断言日志是否包含应有信息的,方法很多
第一种很好理解,是用来判断我们的被测点是否达到预期用的。
第二种用来判断在某种情况下是否会抛出特定的异常,如果会抛出该特定异常,则会判断为断言成功,如果没抛出这种特定异常则会判断为断言失败。
第三种是用来断言日志是否包含应有信息的
assertEqual(a, b, msg=None)断言 a == b assertNotEqual(a, b, msg=None)断言 a != b assertTrue(expr, msg=None)断言 bool(expr) is True assertFalse(expr, msg=None)断言 bool(expr) is False assertIs(a, b, msg=None)断言 a is b assertIsNot(a, b, msg=None)断言 a is not b assertIsNone(expr, msg=None)断言 expr is None assertIsNotNone(expr, msg=None)断言 expr is not None assertIn(a, b, msg=None)断言 a in b assertNotIn(a, b, msg=None)断言 a not in b assertIsInstance(obj, cls, msg=None)断言 obj is cls instance assertNotIsInstance(obj, cls, msg=None)断言 obj is not cls instance assertRaises(exc, fun, *args, **kwds)断言 fun(*args, **kwds) 是否抛出正确异常, 否则抛出断言异常 assertRaisesRegex(exc, r, fun, *args, **kwds) 断言 fun(*args, **kwds) 是否抛出正确异常,同时可以用正则r去匹配异常信息exc,否则抛出断言异常 assertWarns(warn, fun, *args, **kwds)断言fun(*args, **kwds) raises warn assertWarnsRegex(warn, r, fun, *args, **kwds)断言 fun(*args, **kwds) raises warn and the message matches regex r assertLogs(logger, level) 断言log: 断言log里是否出现期望的信息,如果出现则通过,如果没出现,则断言失败抛出断言异常 assertAlmostEqual(a, b, msg=None, delta=None) round(a-b, 7) == 0 断言a-b约等于0,小数点后默认保留7位 assertNotAlmostEqual(a, b, msg=None, delta=None) round(a-b, 7) != 0 断言不是约等于的情况 assertGreater(a, b, msg=None) a > b 断言大于 assertGreaterEqual(a, b, msg=None) a >= b 断言大于等于 assertLess(a, b, msg=None, msg=None) a < b 断言小于 assertLessEqual(a, b, msg=None) a <= b 断言小于等于 assertRegex(text, regex, msg=None) r.search(s) assertNotRegex(text, regex, msg=None) not r.search(s) assertCountEqual(a, b, msg=None) a and b have the same elements in the same number, regardless of their order assertMultiLineEqual(a, b, msg=None) strings 断言多行字符串 assertSequenceEqual(a, b, msg=None, seq_type=None) sequences 断言序列 assertListEqual(a, b, msg=None) lists 断言List assertTupleEqual(a, b, msg=None) tuples 断言元组 assertSetEqual(a, b, msg=None) sets or frozensets 断言Set assertDictEqual(a, b, msg=None) dicts 断言词典
在早期的python版本中,断言函数的写法有些已经被废弃了,如下对应关系所示,在我们使用编译器的时候经常会提示“Deprecated”这个单词,意味着有新的方式取代了当前的实现方法
Method Name Deprecated alias Deprecated alias
assertEqual() failUnlessEqual assertEquals
assertNotEqual() failIfEqual assertNotEquals
assertTrue() failUnless assert_
assertFalse() failIf
assertRaises() failUnlessRaises
assertAlmostEqual() failUnlessAlmostEqual assertAlmostEquals
assertNotAlmostEqual() failIfAlmostEqual assertNotAlmostEquals
assertRegex() assertRegexpMatches
assertNotRegex() assertNotRegexpMatches
assertRaisesRegex() assertRaisesRegexp
二、代码实例
# encoding = utf-8 import unittest import random import logging mylogger = logging.Logger('TestToBeTest') # 被测试类 class ToBeTest(object): @classmethod def sum(cls, a, b): return a + b @classmethod def div(cls, a, b): return a/b @classmethod def return_none(cls): return None # 单元测试类 class TestToBeTest(unittest.TestCase): # assertEqual()方法实例 def test_assertequal(self): try: a, b = 100, 200 sum = 300 # 断言a+b等于sum self.assertEqual(a + b, sum, '断言失败,%s+%s != %s ' %(a, b, sum)) except AssertionError as e: print(e) # 断言log with self.assertLogs('assertlog', level='INFO') as cm: logging.getLogger('assertlog').info('first message') logging.getLogger('assertlog.bar').error('second message') self.assertEqual(cm.output, ['INFO:assertlog:first message', 'ERROR:assertlog.bar:second message']) # assertNotEqual()方法实例 def test_assertnotequal(self): try: a, b = 100, 200 res = -1000 # 断言a-b不等于res self.assertNotEqual(a - b, res, '断言失败,%s-%s != %s ' %(a, b, res)) except AssertionError as e: print(e) # assertTure()方法实例 def test_asserttrue(self): list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] list2 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] list3 = list1[::-1] print(list3) try: # 断言表达式为真 self.assertTrue(list3 == list2, "表达式为假") except AssertionError as e: print(e) # assertFalse()方法实例 def test_assertfalse(self): list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] list2 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] list3 = list1[::-1] try: # 断言表达式为假 self.assertFalse(list3 == list1, "表达式为真") except AssertionError as e: print(e) # assertIs()方法实例 def test_assertis(self): list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] list2 = list1 try: # 断言list2和list1属于同一个对象 self.assertIs(list1, list2, "%s 与 %s 不属于同一对象" % (list1, list2)) except AssertionError as e: print(e) # assertIsNot()方法实例 def test_assertisnot(self): list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] list2 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] try: # 断言list2和list1不属于同一个对象 self.assertIsNot(list2, list1, "%s 与 %s 属于同一对象" % (list1, list2)) except AssertionError as e: print(e) # assertIsNone()方法实例 def test_assertisnone(self): try: results = ToBeTest.return_none() # 断言表达式结果是none self.assertIsNone(results, "is not none") except AssertionError as e: print(e) # assertIsNotNone()方法实例 def test_assertisnotnone(self): try: results = ToBeTest.sum(4, 5) # 断言表达式结果不是none self.assertIsNotNone(results, "is none") except AssertionError as e: print(e) # assertIn()方法实例 def test_assertin(self): try: str1 = "this is unit test demo" str2 = "demo" # 断言str2包含在str1中 self.assertIn(str2, str1, "%s 不被包含在 %s中" %(str2, str1)) except AssertionError as e: print(e) # assertNotIn()方法实例 def test_assertnotin(self): try: str1 = "this is unit test demo" str2 = "ABC" # 断言str2不包含在str1中 self.assertNotIn(str2, str1, "%s 包含在 %s 中" % (str2, str1)) except AssertionError as e: print(e) # assertIsInstance()方法实例 def test_assertisinstance(self): try: o = ToBeTest k = object # 断言测试对象o是k的类型 self.assertIsInstance(o, k, "%s的类型不是%s" % (o, k)) except AssertionError as e: print(e) # assertNotIsInstance()方法实例 def test_assertnotisinstance(self): try: o = ToBeTest k = int # 断言测试对象o不是k的类型 self.assertNotIsInstance(o, k, "%s 的类型是%s" % (o, k)) except AssertionError as e: print(e) # assertRaises()方法实例 def test_assertraises(self): # 测试抛出指定的异常类型 # assertRaises(exception) with self.assertRaises(TypeError) as exc: random.sample([1, 2, 3, 4, 5, 6], "j") # 打印详细的异常信息 print(exc.exception) # assertRaises(exception, callable, *args, **kwds) try: self.assertRaises(ZeroDivisionError, ToBeTest.div, 3, 0) except ZeroDivisionError as e: print(e) # assertRaisesRegexp()方法实例 def test_assertraisesregex(self): # 测试抛出指定的异常类型,并用正则表达式去匹配异常信息 # assertRaisesRegex(exception, regexp) with self.assertRaisesRegex(ValueError, "literal") as exc: int("abc") # 打印详细的异常信息 print(exc.exception) # assertRaisesRegex(exception, regexp, callable, *args, **kwds) try: self.assertRaisesRegex(ValueError, 'invalid literal for.*\'abc\'$', int, 'abc') except AssertionError as e: print(e) # assertLogs()方法实例 def test_assertlogs(self): with self.assertLogs(mylogger) as log: mylogger.error("打开浏览器") mylogger.info('关闭并退出浏览器') self.assertEqual(log.output, ['ERROR:TestToBeTest:打开浏览器', 'INFO:TestToBeTest:关闭并退出浏览器']) if __name__ == '__main__': unittest.main()