25.3.7类和方法
本节深入介绍unittest的接口api
25.3.7.1测试用例
class unittest TestCase(methodName = 'runTest')
TestCase类的实例代表了unittest universe中最小的可测试单元。这个类用来作为基类,具体的测试是通过具体的子类来实现的。这个类实现了测试运行程序所需要的接口 以允许它能够驱动测试, 以及提供了 测试代码可以检查和报告各种失败的 方法。
TestCase的每个实例都将运行一个测试方法: methodName 。如果你还记得,我们之前有这样的例子:
def suite():
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase('test_default_size'))
suite.addTest(WidgetTestCase('test_resize'))
return suite
这里我们创建了两个WidgetTestCase的实例,每个都进行了单独的测试。
methodName默认值是runTest()。
TestCase实例提供了三组方法:一组用来运行测试,一组用来另一组用来测试实现 检查条件和 报告失败,以及一些允许收集测试本身的信息的查询方法。
第一组:
setUp()
用来测试fixture。 在调用测试方法之前调用这个方法,除了AssertionError或SkipTest之外,这个方法所提出的任何错误都会被视为一个错误,而不是一个测试失败。默认的实现什么都不做。
tearDown()
在测试方法调用后立即调用并记录结果。即使测试方法引发异常,也会调用这个方法,因此子类中的实现可能要特别小心的检查内部状态。除了AssertError或SkipTest之外,任何通过这种方法被抛出的异常都将被认为是一个额外的错误,而不是一个测试失败(因此增加爱了报告错误的总数)只有在setUp()成功时才会调用该方法,不管测试方法的结果如何。默认的实现什么都不做。
setUpClass()
在单个类运行测试之前调用的类方法。setUpClass作为唯一的参数被称为类,必须用classmethod()来修饰
@classmethod
def setUpClass(cls):
...
tearDownClass()
在一个独立的类 测试运行 之后调用的类方法。tearDownClass作为唯一的参数被类调用,而且必须用classmethod来修饰
@classmethod
def tearDownClass(cls):
...
run(result = None)
运行测试,将结果收集到测试结果对象中。如果结果被省略或者没有,则创建一个临时结果对象(通过调用defaultTestResult()方法)并使用。结果对象不会返回run()的调用方。只调用TestCase示例也可以产生同样的效果。
skipTest(reason)
在测试 方法或者 setUp()时 可以用这个跳过当前测试。
debug
运行测试而不收集结果。这允许将测试抛出的异常传送给调用者,并且可以用于支持调试器中的运行测试。
第二组:
TestCase类提供几个断言方法来检查和报告失败。下表列除了最常用的方法:
Method | Checks that | New in |
---|---|---|
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 | 2.7 |
assertIsNot(a, b) | a is not b | 2.7 |
assertIsNone(x) | x is None | 2.7 |
assertIsNotNone(x) | x is not None | 2.7 |
assertIn(a, b) | a in b | 2.7 |
assertNotIn(a, b) | a not in b | 2.7 |
assertIsInstance(a, b) | isinstance(a, b) | 2.7 |
assertNotIsInstance(a, b) | not isinstance(a, b) | 2.7 |
所有的断言方法(除了assertRaises(), assertRaisesRegexp())接受一个msg参数,如果指定的话,它被用作失败的错误消息。
assertEqual(first, second, msg=None)
测试第一个值和第二个值是相等的。如果两个值不相等,测试会失败。此外,如果两个值是相同的类型,列表list或者元组tuple或者词典dic或者集合set或者frozenset或者unicode或者任何使用addTypeEqualityFunc()注册的类型的子类,这个特定类型的判等方法将会被调用以生成更有用的默认错误信息
2.7版本改进: 添加了特定类型判等函数的自动调用。
assertNotEqual(first, second, msg=None)
测试两个值是否不相等,如果相等,测试会失败
assertTrue(expr, msg=None)
assertFalse(expr, msg=None)
判断表达式expr是否正确。
注意这相当于bool(expr)是否正确,而不是expr是否正确。当更多具体的方法可用时,这个方法应该被避免,因为他们提供一个更好的错误信息以防失败。
assertIs(first, second, msg=None)
assertIsNot(first, second, msg=None)
测试两者的计算值是否是同一个对象。
assertIsNone(expr, msg=None)
assertIsNotNone(expr, msg=None)
测试表达式是不是空
assertIn(first, second, msg=None)
assertNotIn(first, second, msg=None)
测试第一个值是不是在第二个值之中。
assertIsInstance(obj, cls, msg=None)
assertNotIsInstance(obj, cls, msg=None)
测试obj是或不是cls的实例(它可以是类或类的元组,被isinstance()所支持)
要检查确切类型,使用assertis(type(obj), cls)
还可以使用如下方法检查异常和警告:
Method | Checks that | New in |
---|---|---|
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 | 2.7 |
assertRaises(exception, callable, *args, **kwds)
assertRaises(exception)
当可调用的任何位置或关键字参数被调用时,该异常将会被调用,这些参数也被传递给assertRaises()。
如果异常被抛出,测试通过,如果出现另一个异常,或者不抛出异常,则会出现错误。
为了捕获任何一组异常,包含异常类的tuple可以作为异常传递。
如果只给了异常参数,则返回上下文处理器,这样测试中的代码就可以write inline(内联)而不是作为函数来写。
with self.assertRaises(SomeException):
do_something()
上下文管理器将在异常属性中存储捕获的异常对象。如果目的是对所提出的的异常进行额外的检查,这就很有用了:
with self.assertRaises(SomeException) as cm:
do_something()
the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)
在2.7中增加了使用assertRaises()作为一个上下文管理器
assertRaisesRegexp(exception, regexp, callable, *args, **kwds)
assertRaisesRegexp(exception, regexp)
和assertRaises()一样但是也测试了regexp正则表达式匹配被抛出异常的字符串。
regexp 可能是一个正则表达式对象,或者一个包含正则表达式的字符串,用于re.search()
self.assertRaisesRegexp(ValueError, "invalid literal for.*XYZ'$",int, 'XYZ')
or:
with self.assertRaisesRegexp(ValueError, 'literal'):
int('XYZ')
还有其他的方法用来执行更多的具体检查:
Method | Checks that | New in |
---|---|---|
assertAlmostEqual(a, b) | round(a-b, 7) == 0 | |
assertNotAlmostEqual(a, b) | round(a-b, 7) != 0 | |
assertGreater(a, b) | a > b | 2.7 |
assertGreaterEqual(a, b) | a >= b | 2.7 |
assertLess(a, b) | a < b | 2.7 |
assertLessEqual(a, b) | a <= b | 2.7 |
assertRegexpMatches(s, r) | r.search(s) | 2.7 |
assertNotRegexpMatches(s, r) | not r.search(s) | 2.7 |
assertItemsEqual(a, b) | sorted(a) == sorted(b) and works with unhashable objs | 2.7 |
assertDictContainsSubset(a, b) | all the key/value pairs in a exist in b | 2.7 |
assertAlmostEqual(first, second, places=7, msg=None, delta=None)
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)
测试第一个和第二个值大约(或不大约)相等,计算差额,四舍五入到给定的十进制数(默认值7),然后将其与零进行比较。 注意这些方法将四舍五入这些值 按照给定的小数位数(例如round() 函数),而不是有效数字。
如果提供了delta而不是places,那么两个值的差一定小于或者等于delta。
delta和places都提供的话就会触发一个类型错误。
在版本2.7中 assertAlmostEqual自动考虑 相等 ,如果两个对象相等,assertNotAlmostEqual()会自动判定失败。添加了delta参数。
assertGreater(first, second, msg=None)
assertGreaterEqual(first, second, msg=None)
assertLess(first, second, msg=None)
assertLessEqual(first, second, msg=None)
测试第一个值 >, >=, < 或者 <=第二个值。如果不满足,测试会判定失败。
>>>
>>> self.assertGreaterEqual(3, 4)
AssertionError: "3" unexpectedly not greater than or equal to "4"
assertRegexpMatches(text, regexp, msg=None)
测试一个正则表达式在一段文本中匹配到了。以防失败,错误信息会包含正则表达式和 文本内容。(或者意外匹配的模式和部分文本)。 regexp 可能是一个正则表达式对象,或者一个包含正则表达式的字符串,用于re.research()。
assertNotRegexpMatches(text, regexp, msg=None)
验证regexp匹配不到文本。错误消息包括模式和匹配的部分文本。regexp可能是一个正则表达式对象,或者一个包含正则表达表达式的字符串,用于 re.search()。
assertItemsEqual(actual, expected, msg=None)
忽略顺序, 测试 预测的序列 和实际的序列 包含相同的元素。当它们不存在时,将产生一个错误消息,列出序列之间的差异。
在比较实际和期望时,不忽略重复的元素。它验证是否每个元素在两个序列中都有相同的计数。
它相当于assertEqual(sorted(expected), sorted(actual))
但它也适用于一系列的可hash对象。
assertDictContainsSubset(expected, actual, msg=None)
测试字典中的键值对是否为预期中的父集。如果不是,将生成错误信息,列出丢失的键和不匹配的值。
**assertEqual()将相同类型的对象的 等同性检查 分派到不同的类型特定的方法。
法已经为大多数内置类型实现, 但是也可以使用addTypeEqualityFunc()来注册新方法。**
addTypeEqualityFunc(typeobj, function)
注册一个名为assertEqual()的特定类型的方法,以检查相同类型的obj(不是子类)的两个对象是否相等。
函数必须采用两个参数位置和第三个msg = 无关键字参数, 正如assertEqual()所做的。
当检测到强两个参数之间的不平等时,它必须抛出self.failureexception(msg)异常–可能提供有用的信息,并解释错误消息中的不相等细节。
下表总结了assertEqual()自动使用的特定类型的方法(注意:通常不需要直接调用这些方法)
Method | Used to compare | New in |
---|---|---|
assertMultiLineEqual(a, b) | strings | 2.7 |
assertSequenceEqual(a, b) | sequences | 2.7 |
assertListEqual(a, b) | lists | 2.7 |
assertTupleEqual(a, b) | tuples | 2.7 |
assertSetEqual(a, b) | sets or frozensets | 2.7 |
assertDictEqual(a, b) | dicts | 2.7 |
assertMultiLineEqual(first, second, msg=None)
测试多行字符串 第一行等于第二行。 当不等于时, 两个字符串的diff会突出显示在错误消息中。这种方法在比较字符串和assertEqual()时是默认使用的。
assertSequenceEqual(seq1, seq2, msg=None, seq_type=None)
测试两个序列相等。 如果提供了seq_type, 则seq1 和seq2 都必须是seq_type的实例,否则会报错。如果序列是不同的则声明一个显示两者差异的错误消息。这个方法不是assertEqual()直接调用的,但是它用于实现assertEqual()和assertTupleEqual()。
assertListEqual(list1, list2, msg=None)
assertTupleEqual(tuple1, tuple2, msg=None)
测试两个列表或者两个元组是一样的 。 如果没有,则生命一个只显示两者之间不同的错误消息。如果两个参数都是错误的类型,也会出现错误。在比较列表或元组与assertEqual()时,这些方法是默认使用的 。
assertSetEqual(set1, set2, msg=None)
测试两个集合是相同的 。 如果不,一个列出两个集合不同的错误消息会被声明。这个方法被assertEqual()用来比较集合 和frozensets。如果set1和set2 都没有set.difference()方法,则失败。
assertDictEqual(expected, actual, msg=None)
测试两个字典是相等的。如果没有,则声明一个显示字典差异的错误消息。默认情况下,该方法将用于比较嗲用assertEqual()的字典。
第三组
TestCase 也提供了这些方法和属性:
fail(msg=None)
对错误消息 使用msg或none 无条件的向测试失败发出信号
failureException
这个类属性给出了测试方法所提出的的异常。 如果一个测试框架需要使用一个专门的异常,可能要携带额外的信息,那么它必须将这个异常子类化, 以便公平的使用框架。
此属性的初始值为AssertionError
longMessage
如果设置为True,那么你传递给assert方法的任何显式错误信息会被附加到正常失败消息的末尾。正常的消息包含 有关涉及对象的有用信息,例如来自assertEqual的消息显式了两个不相等对象的repr 将此属性设置为True可以使您在正常情况下添加自定义错误消息。
此属性默认为False, 这意味着传递给assert方法的自定义消息将使 原来的消息无效。
在调用assert方法之前,通过将实例属性指定为True或False,可以在单个测试中覆盖类的 设置。
maxDiff
该属性通过assert方法控制输出的最大长度,该方法报告失败的问题。它默认为80*8个字符。assert 受此属性影响的方法是assertSequenceEqual()(包括委托给它的所有序列比较方法)、assertDictEqual()和assertMultiLineEqual()
将maxDiff设置为None, 意味着没有最大长度的扩散
测试框架可以使用以下方法来收集测试信息
countTestCases()
返回由这个测试对象表示的测试数。对于TestCase实例,它总是1
defaultTestResult()
返回应该用于这个测试用例类的测试结果类的实例(如果没有提供给run()方法的其他结果实例。
对于TestCase实例,这将始终是TestResult的一个实例。Testcase的子类应该在必要时重写这个实例。
id()
返回指定特定测试用例的字符串。这通常使测试方法的全名,包括模块和类名。
shortDescription()
返回测试的描述,如果没有提供描述,则没有。如果可用的话,该方法的默认实现返回测试方法的docstring的第一行,或者None
addCleanup(function, *args, **kwargs)
在teardown()之后添加一个函数, 用于在测试期间使用的清理资源。函数将按顺序调用, 以使他们被添加(LIFO)。他们被添加到addCleanup()中的任何参数和关键字参数。
如果setUp()失败,意味着不调用tearDown(), 那么添加的任何清除函数都将被调用。
doCleanups()
这个方法在tearDown()之后被无条件调用。如果setUp引发异常。则调用setUp().
它负责调用addCleanup()添加的所有清理函数。如果您需要在tearDown()之前调用清理函数,那么您可以调用doCleanups()自己。
doCleanups()每次从 清除函数堆 中取出方法,因此可以随时调用它。
class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)
这个类实现了TestCase接口的一部分, 它允许测试运行器驱动测试,但是不提供测试代码用来检查和报告错误的方法。这用于创建使用遗留测试代码的测试用例,允许它集成到一个机遇unittest的测试框架中