类和方法
本节将深入介绍unittest的API。
测试用例
class unittest.TestCase(methodName='runTest')
TestCase类的实例表示unittest核心的逻辑测试单元。这个类用作基类,具体的测试则通过具体的子类来实现。这个类实现了测试程序所需的并允许它进行驱动测试的接口,以及提供了可用于检查和报告各种故障的方法。
TestCase的每个实例都会运行一个基本方法:methodName方法。在TestCase的大多数用法中,既不需要更改methodName,也不需要重新实现默认的runTest()
方法。
版本3.2的更改:TestCase不需要提供的methodName来实例化。这样可以更轻松地从交互式解析器中使用TestCase。
TestCase实例提供的三组方法:一组用于运行测试,另一组用于检查条件和报告失败,以及一些允许收集测试本身的信息的查询方法。
第一组(运行测试)方法:
setUp()
用来测试fixture。在调用测试方法之前调用它;除了AssertError或SkipTest之外,这个方法引发的任何异常都会被视为错误,而非测试失败。默认的实现是什么都不做。
tearDown()
在测试方法之后立即调用并记录结果。即使测试方法出现异常,也会调用此方法,因此子类的实现可能需要特别注意检查内部状态。由此方法引发的任何异常(AssertError或SkipTest除外)都会被视为错误而非测试失败(从而增加报告错误的总数)。只有在setUp()方法执行成功时才会调用此方法,而不管测试方法的结果如何。默认的实现是什么都不做。
setUpClass()
在单个类运行测试之前调用的类方法。setUpClass
使用类作为唯一的参数调用,并且必须用classmethod()修饰:
@classmethod
def setUpClass(cls):
...
有关详细信息,请参考类和模块夹具。
版本3.2定义。
tearDownClass()
在单个类运行测试之后调用的类方法。tearDownClass
使用类作为唯一的参数调用,并且必须用classmethod()修饰:
@classmethod
def tearDownClass(cls):
...
有关详细信息,请参考类和模块夹具。
版本3.2定义。
run(result=None)
运行测试,将结果收集到测试结果对象TestResult中。如果结果被省略或为None
,则创建一个临时结果对象(通过调用defaultTestResult方法)并使用。结果对象返回给run()的调用者。
只调用TestCase实例也可以产生相同的效果。
版本3.3的更改:以前版本的运行未返回结果。也没有调用实例。
skipTest(reason)
在测试方法或setUp()方法可以用它来跳过当前测试。有关详细信息,请参考跳过测试和预期的故障。
版本3.1定义。
subTest(msg=None, \*params*)
返回一个执行封闭的代码块作为子测试的上下文管理器。msg和params是可选的,任何值都会在子测试失败时显示,允许你清楚地失败它们。
一个测试用例可以包含任意数量的子测试声明,并且可以任意嵌套。
有关详细信息,请参考使用子测试区分测试迭代。
debug()
测试调试且不收集结果。它允许将测试抛出的异常传送给调用者,并可用于支持在调试器下运行测试。
本TestCase类提供了一些断言方法来检查并报告故障。下表列出了最常用的方法(有关更多断言方法,请参阅下表):
方法 | 检查内容 | 定义版本 |
---|---|---|
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 |
3.1 |
assertIsNot(a, b) | a is not b |
3.1 |
assertIsNone(x) | x is None |
3.1 |
assertIsNotNone(x) | x is not None |
3.1 |
assertIn(a, b) | a in b |
3.1 |
assertNotIn(a, b) | a not in b |
3.1 |
assertIsInstance(a, b) | isinstance(a, b) |
3.2 |
assertNotIsInstance(a, b) | not isinstance(a, b) |
3.2 |
所有断言方法都接受一个msg参数,如果指定,该参数将用作失败时的错误消息(另请参阅longMessage)。请注意,关键字参数只有当它们被用作上下文管理器时才可以传递给assertRaises(), assertRaisesRegex(),assertWarns(),assertWarnsRegex()。
assertEqual(first, second, msg=None)
用来测试first和second是否相等。如果两个值不相等,则测试失败。
如果first和second是完全相同的类型,如list,tuple,dict,set,frozenset或str之一,或者任何使用addTypeEqualityFunc()向特定类型的相等函数注册的子类的特定类型,这个特定类型的相等方法会生成更有用的默认错误信息(另请参见特定类型的方法列表)。
版本3.1的更改:添加了自动调用特定类型的相等方法。
版本3.2的更改:assertMultiLineEqual()添加为用于比较字符串的默认类型的相等函数。
assertNotEqual(first, second, msg=None)
用来测试first和second是否不相等。如果两个值相等,则测试失败。
assertTrue(expr, msg=None)
assertFalse(expr, msg=None)
用来测试expr是否为真(或为假)。
请注意,它实现的是bool(expr) is True
而不是expr is True
(对于后者,使用assertIs(expr, True)
)。当有更多其它可用的方法(如用assertEqual(a, b)
替换assertTrue(a == b)
)时,应该避免使用它,因为它们在用例失败时抛出更好的错误消息提示。
assertIs(first, second, msg=None)
assertIsNot(first, second, msg=None)
用来测试first和second是否是(或不是)相同类型。
版本3.1定义。
assertIsNone(expr, msg=None)
assertIsNotNone(expr, msg=None)
用来测试expr是否为(或不为)None
。
版本3.1定义。
assertIn(first, second, msg=None)
assertNotIn(first, second, msg=None)
用来测试first包含于(或不包含于)second。
版本3.1定义。
assertIsInstance(obj, cls, msg=None)
assertNotIsInstance(obj, cls, msg=None)
用来测试obj是(或不是)cls的实例(它可以是被isinstance支持的类或者元组)。如果要检查确切的类型,使用assertIs(type(obj), cls)。
版本3.2定义。
还可以使用以下方法检查异常、警告和日志信息。
方法 | 检查内容 | 定义版本 |
---|---|---|
assertRaises(exc, fun, args, *kwds) | fun(*args, **kwds) 抛出exec |
|
assertRaisesRegex(exc, r, fun, args, *kwds) | fun(*args, **kwds) 抛出exc和匹配正则表达式r的消息 |
3.1 |
assertWarns(warn, fun, args, *kwds) | fun(*args, **kwds) 抛出警告 |
3.2 |
assertWarnsRegex(warn, r, fun, args, *kwds) | fun(*args, **kwds) 抛出警告和匹配正则表达式r的消息 |
3.2 |
assertLogs(logger, level) | 最低级别的with 块日志 |
3.4 |
assertRaises(exception, callable, \args, **kwds*)
assertRaises(exception, \, msg=None*)
用来测试在任何位置或通过传递给assertRaises()的关键字参数调用callable,抛出的异常。如果抛出异常,则测试通过,如果出现另外的异常则会出现错误,如果没有抛出异常,则会测试失败。要捕获任何一组异常,可以将包含异常类的元组作为exception进行传递。
如果只给定exception和可能的msg,则返回一个上下文管理器,以便测试中的代码可以内联,而不是作为一个函数来编写:
with self.assertRaises(SomeException):
do_something()
当用作上下文管理器时,assertRaises()可以接受关键字参数msg。
上下文管理器会将捕获的异常对象存储在它的exception属性中。如果打算对抛出的异常进行额外的检查,这可能是非常有用的:
with self.assertRaises(SomeException) as cm:
do_something()
the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)
版本3.1的更改:添加了assertRaises()用作上下文管理器的功能。
版本3.2的更改:添加了exception属性。
版本3.3的更改:在用作上下文管理器时添加了msg关键字参数。
assertRaisesRegex(exception, regex, callable, \args, **kwds*)
assertRaisesRegex(exception, regex, \, msg=None*)
与assertRaises()相似,但也测试用regex正则匹配字符串时抛出的异常。regex可以是一个正则表达式对象,也可以是使用于re.search()的包含正则表达式的字符串。例如:
self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$",
int, 'XYZ')
或者:
with self.assertRaisesRegex(ValueError, 'literal'):
int('XYZ')
版本3.1定义:命名为assertRaisesRegexp
。
版本3.2的更改:重命名为assertRaisesRegex()
。
版本3.3的更改:在用作上下文管理器时,增加关键字参数msg。
assertWarns(warning, callable, \args, **kwds*)
assertWarns(warning, \, msg=None*)
用来测试在任何位置或通过传递给assertWarns()的关键字参数调用callable,抛出的警告。如果测试通过,则warning会被触发,反之不会被触发。任何其它异常都是错误的。要捕获任何一组警告,可以将包含警告类的元组作为warnings进行传递。
如果只给定warning和可能的msg,则返回一个上下文管理器,以便测试中的代码可以内联,而不是作为一个函数来编写:
with self.assertWarns(SomeWarning):
do_something()
当用作上下文管理器时,assertWarns()可以接受关键字参数msg。
上下文管理器会将捕获的警告对象存储在它的warning属性中,并且将触发警告的源代码行存储在filename和lineno对象中。如果打算对触发的警告进行额外的检查,这可能是非常有用的:
with self.assertWarns(SomeWarning) as cm:
do_something()
self.assertIn('myfile.py', cm.filename)
self.assertEqual(320, cm.lineno)
调用此方法时,无论是哪一种警告,它都有效。
版本3.2定义。
版本3.3的更改:在用作上下文管理器时添加了msg关键字参数。
assertWarnsRegex(warning, regex, callable, \args, **kwds*) assertWarnsRegex(warning, regex, \, msg=None*) 与assertWarns()类似,但也测试用regex正则匹配字符串时抛出的警告。regex可以是一个正则表达式对象,也可以是使用于re.search()的包含正则表达式的字符串。例如:
self.assertWarnsRegex(DeprecationWarning,
r'legacy_function\(\) is deprecated',
legacy_function, 'XYZ')
或者:
with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'):
frobnicate('/etc/passwd')
版本3.2定义。
版本3.3的更改:在用作上下文管理器时添加了msg关键字参数。
assertLogs(logger=None, level=None)
一个上下文管理器,用于测试至少一条日志记录在logger或它的子日志中,包括给定日志最低级别level。
如果给定logger,它必须是logging.Logger对象或一个给定logger名称的str。默认是捕获所有信息的根logger。
如果给定level,它必须是数字类型的日志等级或一个等价的字符串(例如,“ERROR”
或者logging.ERROR
)。默认是logging.INFO
。
如果with
块中至少有一条匹配到对应级别的日志消息,则测试通过,否则失败。
通过上下文管理器返回的对象是一个可以记录匹配到的日志消息的日志助手。它有两个属性:
records
匹配到的日志消息的logging.LogRecord对象列表。
output
匹配消息的格式化输出的str对象列表。
例如:
with self.assertLogs('foo', level='INFO') as cm:
logging.getLogger('foo').info('first message')
logging.getLogger('foo.bar').error('second message')
self.assertEqual(cm.output, ['INFO:foo:first message',
'ERROR:foo.bar:second message'])
版本3.4定义。
还有更多用来检查其它信息的其它方法,例如:
方法 | 检查内容 | 定义版本 |
---|---|---|
assertAlmostEqual(a, b) | round(a-b, 7) == 0 |
|
assertNotAlmostEqual(a, b) | round(a-b, 7) != 0 |
|
assertGreater(a, b) | a > b |
3.1 |
assertGreaterEqual(a, b) | a >= b |
3.1 |
assertLess(a, b) | a < b |
3.1 |
assertLessEqual(a, b) | a <= b |
3.1 |
assertRegex(s, r) | r.search(s) |
3.1 |
assertNotRegex(s, r) | not r.search(s) |
3.2 |
assertCountEqual(a, b) | a and b have the same elements in the same number, regardless of their order | 3.2 |
assertAlmostEqual(first, second, places=7, msg=None, delta=None)
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)
用来测试通过计算first和second两个参数差值,四舍五入到指定位数(默认小数点后7位),与0比较,是否近似(或不近似)于0。请注意,这些方法将数值四舍五入到给定的小数位数(如round()函数),而不是有效数字。
如果用delta替换了places,那么两个值的差一定小于或等于(或大于)delta。
delta和places都提供的话,会触发TypeError。
版本3.2的更改:assertAlmostEqual()是如果两个比较对象几乎相等,自动认为相等。assertNotAlmostEqual()如果两个对象相等,自动认为失败。添加了delta关键字。
assertGreater(first, second, msg=None)
assertGreaterEqual(first, second, msg=None)
assertLess(first, second, msg=None)
assertLessEqual(first, second, msg=None)
用来测试第一个值first >,>=,< 或者 <= 第二个值second。如果不满足,则测试会判定为失败。
>>> self.assertGreaterEqual(3, 4)
AssertionError: "3" unexpectedly not greater than or equal to "4"
版本3.1定义。
assertRegex(text, regex, msg=None)
assertNotRegex(text, regex, msg=None)
用来测试通过regex正则搜索匹配(或不匹配)文本。如果失败,错误消息会包含正则表达式和文本内容(或意外匹配的模式和部分文本)。regex可以是一个正则表达式对象,也可以是使用于re.search()的包含正则表达式的字符串。
版本3.1定义:命名为assertRegexpMatches
。
版本3.2的更改:方法assertRegexpMatches()
重命名为assertRegex()。
版本3.2定义:assertNotRegex()。
版本3.5定义:弃用assertNotRegexpMatches,替换为assertNotRegex()。
assertCountEqual(first, second, msg=None)
用来测试列表first与列表second是否含有相同的元素,而不管元素顺序是否相同。如果不满足元素相同,则生成包含两个列表之间的差异的错误消息。
比较first和second时,不会忽略重复的元素。它验证每个元素在两个列表中是否具有相同的计数。相当于assertEqual(Counter(list(first)), Counter(list(second)))
,但也适用于重复的非哈希对象。
版本3.2定义。
assertEqual()方法将相同类型的对象的相等性检查分派给不同类型对应特定的方法。这些方法已经针对大多数内置类型实现,但也可以用addTypeEqualityFunc()去注册新方法。
addTypeEqualityFunc(typeobj, function)
注册一个被assertEqual()调用的特定类型的方法,用来检查两个完全相同的typeof(不是子类)对象是否相等。函数必须带有两个参数和第三个类似于assertEqual()的关键字参数msg=None。当检查到前两个参数不相等时,它必须抛出self.failureException(msg)异常-可能提供的有用的信息并解析错误信息内容。
版本3.1定义。
下表汇总了自动使用特定的assertEqual()类型的方法。请注意,一般不需要直接调用这些方法。
方法 | 用于比较 | 定义版本 |
---|---|---|
assertMultiLineEqual(a, b) | 字符串strings | 3.1 |
assertSequenceEqual(a, b) | 序列sequences | 3.1 |
assertListEqual(a, b) | 列表lists | 3.1 |
assertTupleEqual(a, b) | 元组tuples | 3.1 |
assertSetEqual(a, b) | sets或frozensets | 3.1 |
assertDictEqual(a, b) | 字典dicts | 3.1 |
assertMultiLineEqual(first, second, msg=None)
用来测试多行字符串first与字符串second是否相等。如果不等,则在错误信息中突出显示两者差异。当用assertEqual()比较字符串时,默认使用此方法。
版本3.1定义。
assertSequenceEqual(first, second, msg=None, seq_type=None)
用来测试两个序列是否相等。如果提供了seq_type参数,则first和second必须是seq_type的实例,否则测试失败。如果两个序列不同,则构造一个错误信息,显示两者之间的差异。
此方法不是直接调用assertEqual(),而是用于实现assertListEqual()和assertTupleEqual()。
版本3.1定义。
assertListEqual(first, second, msg=None)
assertTupleEqual(first, second, msg=None)
用来测试两个列表list或元组tuples是否相等。如果不等,则构造一个错误信息,显示两者的差异。如果其中一个参数的类型错误,也会抛出错误。当用assertEqual()比较列表和元组时,默认使用这些方法。
版本3.1定义。
assertSetEqual(first, second, msg=None)
用来测试两个sets是否相等。如果不等,则构造一条错误信息,显示两个sets的差异。当用assertEqual()比较sets或者frozensets时,默认使用这个方法。
版本3.1定义。
assertDictEqual(first, second, msg=None)
用来测试两个字典是否相等。如果不等,则构造出一个错误信息,显示两个字典的差异。当用assertEqual()比较字典时,默认使用这个方法。
版本3.1定义。
fail(msg=None)
抛出包含msg或None的测试失败的错误信息。
failureException
这个属性给出了测试方法抛出的异常。如果测试框架需要使用专门的异常,可能需要携带额外的信息,那么它必须将这个异常子类化,以示“公平”。该属性的初始值为AssertionError。
longMessage
这个属性将自定义的错误信息作为msg参数传递给失败的assertXYY。默认值为True。在这种情况下,自定义信息会附加到标准错误消息的末尾。设置为False时,自定义消息将替换标准错误信息。
在调用断言方法之前,将实例属性self.longMessage置为True或False,可以在单个测试方法中覆盖类设置。
每次测试方法调用之前都会重置类设置。
版本3.1定义。
maxDiff
这个属性通过断言方法控制差异输出的最大长度。受此影响的断言方法是assertSequenceEqual()(包括委托给它的所有列表的比较方法),assertDictEqual()和assertMultiLineEqual()。
设置maxDiff为None表示没有最大差异长度。
版本3.2定义。
测试框架可以使用以下方法收集有关测试的信息:
countTestCases()
返回此测试对象的测试数量。在TestCase中,这将永远是1。
defaultTestResult()
返回测试结果类的一个实例(如果没有未run()方法提供其他结果实例)。
在TestCase中,这将永远是一个TestResult实例;TestCase子类根据需要覆盖它。
id()
返回标识特定测试用例的字符串。这通常是测试方法的全名,包括模块和类名。
shortDescription()
返回测试的描述,如果None则没有返回描述。此方法的默认实现返回测试方法的文档字符串的第一行(如果可用)或返回None。
版本3.1的更改:在3.1中,即使存在docstring,也会将测试名称添加到简短描述中。这导致了单元测试扩展的兼容性问题,并且添加测试名称已移至TextTestResultPython3.2中。
addCleanup(function, \args, **kwargs*)
添加一个函数清理测试过程中使用的资源,用于在tearDown()之后调用。函数将按照其添加的顺序(LIFO)以相反的顺序调用。当它们通过addCleanup()添加时,可以通过任何参数或关键字参数来调用。
如果setUp()失败,意味着tearDown()没有被调用,那么仍然会调用添加的任何清理函数。
版本3.1定义。
doCleanups()
这个方法在tearDown()之后无条件地被调用,或者在setUp()之后调用,如果setUp()抛出异常。
它负责调用所添加的所有清理函数addCleanup()。如果你需要在tearDown()之前调用清理函数,那么你可以调用doCleanups()。doCleanups()可以从堆栈中一次抛出一个清理函数,因此你可以随时调用它。
版本3.1定义。
class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)
这个类实现TestCase接口的一部分,允许通过测试runner驱动测试,但不提供用于测试代码检查和报告错误的方法。它使用传递测试代码创建测试用例,从而将其继承到基于测试框架unittest中。
不推荐的别名
由于历史原因,某些TestCase方法具有一个或多个现已弃用的别名。下表列出了正确的名称及其弃用的别名:
方法名称|不推荐使用的别名|不推荐使用的别名
——|——|——
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
从版本3.1开始不推荐使用:第二列列出的fail*别名。
从版本3.2开始不推荐使用:第三列列出的assert*别名。
从版本3.2开始不推荐使用:assertRegexpMatches
和assertRaisesRegexp
已更名为assertRegex()和assertRaisesRegex()。
分组测试
class unittest.TestSuite(tests=())
这个类表示各个测试用例和测试套件的集合。该类提供了测试运行器所需的接口,以允许它像任何其他测试用例一样运行。运行TestSuite实例与迭代套件相同,单独运行每个测试。
如果给出了测试,它必须是可用于最初构建套件的单个测试用例或其他测试套件的迭代。它还提供了其它方法,以便之后将测试用例和套件添加到集合中。
TestSuite对象的行为与TestCase对象非常相似,只是它们并未实际上实现测试。相反,它们用于将测试聚合到应该一起运行的测试组中。可以使用一些其它方法向TestSuite实例添加测试。
addTest(test)
添加一个TestCase或TestSuite到套件中。
addTests(tests)
将迭代的TestCase和TestSuite实例中的所有测试用例添加到此测试套件中。
这相当于对每个元素调用addTest()来迭代测试。
run(result)
运行与此套件相关的测试,将结果收集到作为结果传递的测试结果对象中。请注意,不同于TestCase.run(),TestSuite.run()需要传入结果对象。
debug()
运行与此套件相关的测试而不收集结果。这允许将测试引发的异常传递给调用者,并且可以用来支持在调试器下运行测试。
countTestCases()
返回此测试对象表示的测试数量,包括所有单个的测试和子套件。
__iter__()
通过TestSuite分组测试总是通过迭代进行访问。子类可以通过覆盖来懒惰地提供测试iter()。请注意,可以在单个套件上多次调用此方法(例如,在计算测试或比较相等性时),因此之前重复迭代返回的测试TestSuite.run()对于每次调用迭代必须相同。在TestSuite.run()之后,调用者不应该依赖此方法返回的测试,除非调用者使用子类覆盖TestSuite._removeTestAtIndex()
来保留测试引用。
版本3.2的更改:在早期版本中,TestSuite直接访问测试而不是通过迭代进行测试,因此覆iter()不足以提供测试。
版本3.4的更改:在早期版本中,TestSuite在TestSuite.run()之后保持对每个TestCase的引用。
加载和运行测试
class unittest.TestLoader
TestLoader类被用来创建类和模块的测试套件。通常不需要创建这个类的实例;unittest模块提供了一个可以共享的实例unittest.defaultTestLoader。但是,使用子类或实例可以自定义一些可配置的属性。
TestLoader对象具有以下属性:
errors
当加载测试时发生的非致命错误列表。在任何时候都不会重置加载程序。致命的错误由相关的方法抛出信息,该方法会向调用者抛出异常。非致命错误则由综合的测试抛出,该测试将在运行时抛出原始错误。
版本3.5定义。
TestLoader对象具有以下方法:
loadTestsFromTestCase(testCaseClass) 返回包含在[TestCase]-derived中的所有测试用例的套件testCaseClass。
测试用例的实例通过getTestCaseNames()被创建为每个方法名。默认情况下,这些方法名都是以test开头的。如果getTestCaseNames()没有返回方法,但实现了该方法,则runTest()方法会为该方法创建一个测试用例。
loadTestsFromModule(module, pattern=None)
返回给定模块中的包含的所有测试用例的套件。这个方法通过查找模块以找到TestCase的派生类,以及为该类中定义的每个测试方法创建该类的实例。
注意:虽然使用TestCase-derived类的层次结构可以方便地共享fixture和helper函数,而直接在实例化的基类上定义测试方法并不能很好地使用此方法。但是当测试夹不相同或在子类中定义时,这样做会非常有用。 |
load_tests
函数,则会调用它来加载测试。这就允许模块自定义加载测试。这是load_tests协议。pattern作为第三个参数传递给load_tests
。
版本3.2的更改:支持添加load_test
。
版本3.5的更改:弃用并忽略未记录和非官方的use_load_tests默认参数,但仍可接受向后兼容性。该方法还可以接收一个唯一的作为第三个参数传递给load_tests
的关键字pattern。
loadTestsFromName(name, module=None)
给定一个字符串说明符,返回所有测试用例的套件。
这个说明符是一个虚拟名,它可以解析模块,测试用例类,测试用例类中的测试方法, TestSuite实例或者一个返回TestCase或TestSuite实例的可调用对象。这些检查按此处列出的顺序进行; 也就是说,可能测试用例类里面的方法将被选为“测试用例类中的测试方法”,而不是“可调用对象”。
例如,如果你的模块SampleTests包含TestCase-derived类SampleTestCase里三个测试方法(test_one(),test_two()和test_three()),则说明符'SampleTests.SampleTestCase'
将使此方法返回一个可以运行所有三个测试方法的套件。使用说明符'SampleTests.SampleTestCase.test_two'
会使它返回一个只运行test_two()方法的测试套件。说明符能够引用尚未导入的模块和包;它们将作为附加作用导入。
该方法可选地解析相对于给定module的name。
版本3.5的更改:如果在遍历name时发生ImportError或AttributeError,则运行时会返回综合测试的错误。这些错误会积累在self.errors中。
loadTestsFromNames(names, module=None)
和loadTestsFromName()类似,但使用的是一系列名称而不是单个名称。它的返回值是一个支持未所有测试用例定义每个名称的测试套件。
getTestCaseNames(testCaseClass)
返回一个在testCaseClass中找到的已排序的方法名称列表;testCaseClass应该是TestCase的一个子类。
discover(start_dir, pattern=’test\.py’, top_level_dir=None*)
通过从指定的起始目录递归到子目录中查找所有测试模块,并返回包含它们的TestSuite对象。仅仅加载匹配pattern的测试文件。(使用shell样式模式匹配。)只加载可导入的模块名称(即有效的Python标识符)。
所有测试模块都必须从项目的顶层导入。如果起始目录不是顶级目录,则必须单独指定顶级目录。
如果导入模块失败(例如由于语法错误),则会将其记录为一个错误,并且继续查找。如果导入失败是由于SkipTest抛出的,则会将其记录为跳过而不是错误。
如果找到包(包含名为file的目录__init__.py
),则将检查包的load_tests功能。如果存在,则会调用package.load_tests(loader, tests, pattern)
。测试查找需要注意确保在调用期间仅检查一次测试,即使load_tests方法自己调用了loader.discover
。
如果load_tests
存在,那么发现并没有递归放入包中,load_tests
负责加载包中的所有测试。
故意不将该模式存储为loader属性,以便包可以继续自己发现。存储了top_level_dir,因此 load_tests
不需要将此参数传递给loader.discover()
。
start_dir可以是虚拟模块的名称以及目录。
版本3.2定义。
版本3.4的更改:导入模块抛出的跳过测试会被记录为跳过,而不是错误。发现方法适用于命名空间包。在导入之前对路径进行排序,以便即使基础文件系统的排序不依赖于文件名,执行顺序也是相同的。
版本3.5的更改:检查找到的包load_tests
,无论他们的路径是否与pattern匹配,因为一个包名不可能和默认模式匹配。
TestLoader的以下属性可以通过在实例上子类化或赋值来配置:
testMethodPrefix
给出方法名称前缀的字符串,将被解释为测试方法。默认值为’test’。
这影响了getTestCaseNames()和所有loadTestsFrom*()方法。
sortTestMethodsUsing
在通过getTestCaseNames()对方法名进行排序和使用所有loadTestsFrom*()方法时,用于比较方法名的函数
suiteClass
从测试列表构造测试套件的调用对象。不需要生成对象的方法。默认值是TestSuite类。
这会影响所有loadTestsFrom*()方法。
testNamePatterns
Unix shell样式通配符测试名称模式列表,测试方法必须在测试套件中匹配它们(参见-v
选项)。
如果此属性不是None
(缺省值),则包含在测试套件中的所有测试方法都必须与此列表中的某个模式匹配。请注意,匹配始终使用fnmatch.fnmatchcase(),因此与传递给-v
选项的模式不同,必须使用*
通配符转换简单子字符串模式。
这会影响所有loadTestsFrom*()方法。
版本3.7定义。
class unittest.TestResult
此类用于编译有关哪些测试成功以及哪些测试失败的信息。
一个TestResult对象存储一组测试的结果。TestCase和TestSuite保证结果能够正确地被记录;因此,作为测试者,不用担心记录测试结果。
构建测试框架unittest可能希望通过运行一组测试生成的TestResult对象用于报告结果;因此通过TestRunner.run()方法可以返回一个TestResult的实例。
TestResult在检查运行一组测试的结果时,实例具有以下属性:
errors
包含TestCase实例的二元组和格式化回溯的字符串列表。每个元组代表一个抛出异常的测试。
failures
包含TestCase实例的二元组和格式化回溯的字符串列表。每个元组代表一个通过TestCase.assert*()方法明确地抛出故障异常的测试。
skipped
包含TestCase实例的二元组和字符串的列表,其中包含跳过测试的原因。
版本3.1定义。
expectedFailures
包含TestCase实例的二元组和格式化回溯的字符串列表。每个元组代表测试用例的预期失败。
unexpectedSuccesses
包含TestCase中标记为预期失败的但已成功的实例的列表。
shouldStop
设置为True
时,通过stop()停止执行测试。
testsRun
到目前为止测试的总数。
buffer
如果设置为true,在startTest()和stopTest()之间被调用时,sys.stdout
和sys.stderr
将会缓存。如果测试失败或错误,收集的输出信息只会显示真正的sys.stdout
和sys.stderr
信息。
版本3.2定义。
failfast
如果设置为true,在第一次失败或错误时调用stop(),则暂停测试运行。
版本3.2定义。
tb_locals
如果设置为true,在回调时显示局部变量。
版本3.5定义。
wasSuccessful()
如果所有测试都通过,返回True
,否则返回False
。
版本3.4的更改:如果有通过expectedFailure()装饰器标记的unexpectedSuccesses,则返回False
。
stop()
当通过设置shouldStop属性为 True 来中止正在运行的测试集时,会调用此方法。TestRunner对象会识别该标识并返回不执行任何其它测试。
例如,当用户通过键盘发出中断信号时,TextTestRunner类会使用此功能来停止测试。实现TestRunner的交互式工具也可以用类似的方式使用它。
TestResult类的以下方法用于维护内部数据结构,并且可以在子类中进行扩展以支持其他报告要求。这对于在运行测试时构建支持交互式报告的工具特别有用。
startTest(test)
在测试将要进行时调用它。
stopTest(test)
无论结果如何,在执行测试用例之后调用。
startTestRun()
在执行任何测试之前调用一次。
版本3.1定义。
stopTestRun()
执行所有测试后调用一次。
版本3.1定义。
addError(test, err)
在测试抛出意外异常时调用。err是由sys.exc_info():(type, value, traceback)
返回的一个元组。
默认实现将元组(test, formatted_err)
附加到实例的errors属性,其中formatted_err是从err派生格式化回调。
addSuccess(test)
在测试用例测试成功时调用。
默认实现是什么都不做。
addSkip(test, reason)
在跳过测试用例时调用。reason是跳过测试的原因。
默认实现将元组(test, reason)附加到skipped实例属性。
addExpectedFailure(test, err)
在测试用例测试失败时调用,但是用expectedFailure()装饰器标记 。
默认实现将元组(test, formatted_err)附加到expectedFailures()实例属性,其中formatted_err是从err派生格式化回。
addUnexpectedSuccess(test)
当测试用例用expectedFailure()装饰器标记成功时调用。
默认实现将测试用例添加到unexpectedSuccesses属性。
addSubTest(test, subtest, outcome)
在子测试结束时调用。test是与测试方法对应的测试用例。 subtest是TestCase自定义描述自测试的实例。
如果outcome是None,则子测试成功。否则,它测试失败,并抛出异常,其中outcome是由sys.exc_info(): (type, value, traceback)
返回的表单样式的元组。
结果成功时,默认实现不执行任何操作,并将子测试失败记录为正常故障。
版本3.4定义。
class unittest.TextTestResult(stream, descriptions, verbosity)
通过TextTestRunner的TestResult的一个具体实现。
版本3.2的更改:此类之前已命名_TextTestResult
。旧名称仍作为别名存在,但已弃用。
unittest.defaultTestLoader
共享的TestLoader类的实例。如果不需要自定义,TestLoader则可以使用此实例而不是重复创建新实例。
class unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, \, tb_locals=False)
实现将结果输出到流的一个基本测试运行器。如果stream为None
,则sys.stderr默认用作输出流。这个类有一些可配置的参数,但基本上非常简单。运行测试套件的图形应用程序应提供备用实现。当将功能添加到unittest时,此类的实现应该能够接受`*kwargs`作为接口构建运行程序的更改。
默认情况下,这个运行器展示了DeprecationWarning,PendingDeprecationWarning,ResourceWarning和ImportWarning,尽管它们默认被忽略掉。由不推荐使用的单元测试方法引起的废弃警告也是特殊的,警告过滤器为'default'
或者'always'
,它们每个模块只出现一次,以避免出现过多的警告消息。这种行为可以使用Python的-Wd或-Wa选项(见警告控制)已经让warning设置为None
。
版本3.2的更改:添加warning
参数。
版本3.2的更改:默认流设置为sys.stderr是在实例化时间时,而不是导入时间。
版本3.5的更改:添加tb_locals参数。
_makeResult()
此方法通过run()返回TestResult
的实例。它不是直接调用的,但可以在子类中重写以提供自定义TestResult
。
_makeResult()
实例化该类或可调用地在TextTestRunner
构造函数中作为resultclass
参数传递。如果不提供resultclass
,默认为TextTestResult。结果类使用以下参数进行实例化:
stream, descriptions, verbosity
run(test)
此方法是TextTestRunner的主要公共接口。这个方法需要一个TestSuite或一个TestCase实例。TestResult通过调用_makeResult()被创建,同时运行测试并将结果打印到stdout。
unittest.main(module=’main‘, defaultTest=None, argv=None, testRunner=None, testLoader=unittest.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None)
一个命令行程序,它从模块加载一组测试并运行它们; 这主要是为了使测试模块可以方便地执行。此函数最简单的用法是在测试脚本的末尾包含以下行:
if name == ‘main‘:
unittest.main()
if name == ‘main‘:
unittest.main(verbosity=2)
defaultTest是一个单一测试中的名称或测试名称可迭代如果经由未指定试验名称来运行的argv。如果它未指定或为None
且未通过argv提供测试名称,则所有在module中发现的测试将被运行。
argv参数可以是传递给程序的选项列表,第一个元素是程序名称。如果它未指定或为None
,则使用sys.argv。
testRunner参数可以是一个测试运行类或一个它的已创建的实例。默认情况下,main
使用退出代码调用sys.exit(),指示运行测试成功或失败。
testLoader参数必须是一个TestLoader实例,并默认为defaultTestLoader。
main
支持通过传入参数从交互式解释器中使用exit=False
。这将在标准输出上显示结果而不调用sys.exit():
>>> from unittest import main
>>> main(module=’test_module’, exit=False)
failfast,catchbreak和buffer参数与命令行选项具有相同的效果。
warnings参数指定的警告过滤器 应该在运行测试中使用。如果它没有指定,且如果将-W选项传递给python,它会保留None
(参见警告控件),否则它设置为'default'
。
调用main
实际上返回TestProgram
类的实例。这会将测试结果存储为result
属性。
版本3.1的更改:exit参数被添加进来。
版本3.2的更改:verbosity, failfast, catchbreak, buffer和warnings参数被添加进来。
版本3.4的更改:defaultTest参数改为同时接受测试名称的迭代。
load_tests协议
版本3.2中定义。
模块或包可以通过实现名为load_tests
的实现方法来定制在测试运行期间或测试发现期间如何从中加载测试。
如果测试模块定义为load_tests
,它将会被TestLoader.loadTestsFromModule()使用以下参数调用:
load_tests(loader, standard_tests, pattern)
其中,pattern直接通过loadTestsFromModule
传递。它默认为None
。
它应该返回一个TestSuite。
loader是进行加载的TestLoader的实例。standard_tests是默认从模块加载的测试。测试模块通常只在标准测试集中添加或删除测试。在将包作为测试发现的一部分加载时使用第三个参数。
从一组特定的TestCase类加载测试的典型load_tests
函数可能显示如下:
test_cases = (TestCase1, TestCase2, TestCase3)
def load_tests(loader, tests, pattern):
suite = TestSuite()
for test_class in test_cases:
tests = loader.loadTestsFromTestCase(test_class)
suite.addTests(tests)
return suite
如果在包含程序包的目录中启动发现,无论是从命令行还是通过调用TestLoader.discover(),__init__.py
都将检查程序包load_tests
。如果该函数不存在,则发现将递归到包中,就像它只是另一个目录一样。否则,load_tests
将使用以下参数调用发现包的测试:
load_tests(loader, standard_tests, pattern)
这应该返回一个表示包中所有测试的TestSuite。(standard_tests
仅包含从__init__.py
收集的测试。)
因为这个pattern是传递给load_tests
,包的模式可以自由地继续(并可能修改)测试发现。一个“不执行任何操作”的load_tests
方法如下所示:
def loadtests(loader, standardtests, pattern):
# top level directory cached on loader instance
this_dir = os.path.dirname(__file)
package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
standard_tests.addTests(package_tests)
return standard_tests
版本3.5的更改:由于匹配的默认模式包名是不可能的,所以发现不再检查匹配模式的包名。