You are here:  Home » Python » – 单元测试框架 – 开发工具(Python教程)(参考资料)

unittest单元测试框架

源代码: Lib / unittest / __ init__.py


(如果您已经熟悉测试的基本概念,可能需要跳到断言方法列表.)

unittest单元测试框架最初受JUnit启发,与其他语言的主要单元测试框架具有相似的风格。它支持测试自动化,共享测试的设置和关闭代码,将测试集合到集合中,以及测试与报告框架的独立性.

为了达到这个目的,unittest以面向对象的方式支持一些重要的概念:

测试夹具
A test fixture表示执行一个或多个测试所需的准备工作,以及任何关联清理操作。这可能涉及,例如,创建临时或代理数据库,目录或启动服务器进程.
测试用例
A test case是单独的测试单位。它检查对特定输入集的特定响应。unittest提供基类,TestCase,可用于创建新的测试用例.
test suite
A test suite是测试用例,测试套件或两者的集合。它用于聚合应该一起执行的测试.
试验跑者
A test runner是一个组件,它协调测试的执行并向用户提供结果。跑步者可以使用图形界面,文本界面,或返回一个特殊值来表示执行测试的结果.

另见

模块doctest
另一个具有不同风味的测试支持模块
简单的Smalltalk测试:带图案
Kent Beck使用模式共享来测试框架的原始论文unittest.
Nose和pytest
第三方单元测试框架,具有较轻的写法测试语法。例如, assert func(10) == 42.
Python测试工具分类法
包含功能测试框架和模拟对象库的Python测试工具的广泛列表.
在Python邮件列表中测试
Python中用于讨论测试和测试工具的特殊兴趣小组

脚本Tools/unittestgui/unittestgui.py在Python源代码发行版中是一个用于测试发现和执行的GUI工具。这主要是为了便于那些新的单元测试使用。对于生产环境,建议测试由持续集成系统驱动,如Buildbot,Jenkinsor Hudson。

基本示例

unittest模块提供了一组丰富的工具来构建和运行测试。本节演示了一小部分工具可以满足大多数用户的需求.

这是一个测试三个字符串方法的简短脚本:

import unittestclass TestStringMethods(unittest.TestCase):    def test_upper(self):        self.assertEqual("foo".upper(), "FOO")    def test_isupper(self):        self.assertTrue("FOO".isupper())        self.assertFalse("Foo".isupper())    def test_split(self):        s = "hello world"        self.assertEqual(s.split(), ["hello", "world"])        # check that s.split fails when the separator is not a string        with self.assertRaises(TypeError):            s.split(2)if __name__ == "__main__":    unittest.main()

通过子类化unittest.TestCase创建一个测试用例。三个单独的测试用名称以字母test。这个命名约定告诉测试运行器哪些方法代表测试.

每个测试的关键是调用assertEqual()检查预期的结果;assertTrue()assertFalse()验证条件;或assertRaises()以验证是否引发了异常异常。使用这些方法代替assert语句,以便测试运行器可以累积所有测试结果并生成报告.

setUp()tearDown()方法允许你使用定义将在每个测试方法之前和之后执行的指令。它们将在部分更详细地介绍。组织测试代码.

最后一个块显示了运行测试的简单方法。unittest.main()提供测试脚本的命令行界面。从命令行运行时,上面的脚本产生一个如下所示的输出:

...----------------------------------------------------------------------Ran 3 tests in 0.000sOK

-v选项传递给测试脚本将指示unittest.main()启用更高级别的冗长,并产生以下输出:

test_isupper (__main__.TestStringMethods) ... oktest_split (__main__.TestStringMethods) ... oktest_upper (__main__.TestStringMethods) ... ok----------------------------------------------------------------------Ran 3 tests in 0.001sOK

上面的例子显示了最常用的unittest足以满足许多日常测试需求的功能。文档的其余部分探讨了第一原理的完整功能集.

命令 – 线程接口

可以从命令行使用unittest模块从模块,类甚至单独的测试方法运行测试:

python -m unittest test_module1 test_module2python -m unittest test_module.TestClasspython -m unittest test_module.TestClass.test_method

您可以传入一个包含模块名称和完全限定类或方法名称组合的列表.

测试模块也可以通过文件路径指定:

python -m unittest tests/test_something.py

这允许您使用shell文件名完成来指定测试模块。指定的文件仍必须可作为模块导入。通过删除’.py’并将路径分隔符转换为’。’将路径转换为模块名称。如果要执行不可作为模块导入的测试文件,则应直接执行该文件.

你可以通过传入-v标志来运行更详细的测试(更高的详细程度):

python -m unittest -v test_module

当没有参数执行时测试发现启动:

python -m unittest

有关所有命令行选项的列表:

python -m unittest -h

在版本3.2中更改:在早期版本中,只能运行单独的测试方法而不是模块或类.

命令行选项

unittest 支持这些命令行选项:

-b, --buffer

在testrun期间缓冲标准输出和标准错误流。通过测试期间的输出被丢弃。输出通常在测试失败或错误时回显并添加到故障消息中.

-c, --catch

Control-C在测试运行期间等待当前测试结束然后报告所有结果到目前为止。第二个 Control-C 引发正常KeyboardInterrupt异常

查看信号处理以获取提供此功能的功能.

-f, --failfast

在第一个错误或失败时停止测试运​​行.

-k

只运行与模式或子字符串匹配的测试方法和类。此选项可以多次使用,在这种情况下,所有测试用例都与给定模式匹配被包含在内。

包含通配符的模式(*)使用fnmatch.fnmatchcase()匹配测试名称;否则使用简单区分大小写的子串匹配

模式与测试加载器导入的完全限定的测试方法名称匹配.

例如,-k foo匹配foo_tests.SomeTest.test_something,bar_tests.SomeTest.test_foo,但不是bar_tests.FooTest.test_something.

--locals

显示局部变量在tracebacks.

版本3.2中的新功能:添加了命令行选项-b, -c-f.

版本3.5:命令行选项--locals.

版本3.7中新增:命令行选项-k.

命令行也可以用于测试发现,运行项目中的所有测试或只是一个子集.

测试发现

版本3.2.

Unittest支持简单的测试发现。为了兼容testdiscovery,所有测试文件必须是 modules (包括命名空间包)可以从项目的顶级目录导入(这意味着他们的文件名必须是有效的身份标识).

测试发现在TestLoader.discover(),但也可以从命令行使用。基本的命令行用法是:

cd project_directorypython -m unittest discover

注意

作为一个快捷方式,python -m unittest相当于python -m unittest discover。如果你想传递参数来测试发现discover必须明确使用子命令.

discover子命令有以下选项:

-v, --verbose

详细输出

-s, --start-directory directory

目录开始发现(.默认)

-p, --pattern pattern

模式匹配测试文件(test*.py默认)

-t, --top-level-directory directory

项目的顶级目录(默认为开始目录)

-s, -p-t选项可以按顺序传递给位置参数。以下两个命令行是等效的:

python -m unittest discover -s project_directory -p "*_test.py"python -m unittest discover project_directory "*_test.py"

除了作为路径之外,还可以传递包名,例如myproject.subpackage.test,作为开始目录。然后将导入您提供的包名称,并将其在文件系统上的位置用作起始目录.

小册子

测试发现通过导入测试来加载测试。一旦测试发现找到了您指定的起始目录中的所有测试文件,就会将路径转换为要导入的包名称。例如 foo/bar/baz.py将被导入为foo.bar.baz.

如果你有一个全局安装的包,并尝试在包的不同副本上进行测试发现,那么导入could发生在错误的地方。如果发生这种情况,测试发现会警告你并退出.

如果您将起始目录作为包名提供而不是通过apath到目录,那么发现假定它导入的任何位置是您想要的位置,因此您将无法获得警告.

测试模块和软件包可以通过load_tests协议自定义测试加载和发现.

版本3.4更改:测试发现支持命名空间包.

组织测试代码

单元测试的基本构建块是test cases – 必须设置并检查正确性的单一场景。在unittest中,测试用例用unittest.TestCase实例。要创建自己的测试用例,必须编写TestCase或使用FunctionTestCase.

的测试代码TestCase实例应完全自我包含,以便它可以单独运行或与任何其他测试用例任意组合运行.

最简单的TestCase子类将简单地实现一个测试方法(即一个名称以test开头的方法),以便执行特定的测试代码:

import unittestclass DefaultWidgetSizeTestCase(unittest.TestCase):    def test_default_widget_size(self):        widget = Widget("The widget")        self.assertEqual(widget.size(), (50, 50))

请注意,为了测试某些东西,我们使用其中一个assert*()提供的方法TestCase基类。如果测试失败,将会出现一个带有解释性消息的异常,并且unittest将测试用例识别为failure。任何其他例外将被视为errors.

测试可以很多,并且它们的设置可以是重复的。幸运的是,我们可以通过实现一个名为setUp()的方法来分解设置代码,测试框架将自动调用我们运行的每个测试:

import unittestclass WidgetTestCase(unittest.TestCase):    def setUp(self):        self.widget = Widget("The widget")    def test_default_widget_size(self):        self.assertEqual(self.widget.size(), (50,50),                         "incorrect default size")    def test_widget_resize(self):        self.widget.resize(100,150)        self.assertEqual(self.widget.size(), (100,150),                         "wrong size after resize")

注意

顺序通过对字符串的内置顺序排序测试方法名称来确定将运行的各种测试.

如果setUp()方法在测试运行时引发异常,框架将认为测试有错误,测试方法不会执行.

同样,我们可以提供一个tearDown()方法,在测试方法运行后整理:

import unittestclass WidgetTestCase(unittest.TestCase):    def setUp(self):        self.widget = Widget("The widget")    def tearDown(self):        self.widget.dispose()

如果setUp()成功,tearDown()会测试测试方法是否成功.

测试代码的工作环境叫做test fixture。创建一个新的TestCase实例作为用于执行每个单独测试方法的唯一测试夹具。因此setUp(), tearDown()__init__()每次测试都会被调用一次

建议您使用TestCase实现将测试分组,以根据他们测试的功能进行分组。unittest提供了一个机制:test suite,由unittest表示TestSuite类。在大多数情况下,调用unittest.main()将是正确的事情,并为您收集所有模块的测试用例并执行它们.

但是,如果您想自定义测试套件的构建,您可以做你自己:

def suite():    suite = unittest.TestSuite()    suite.addTest(WidgetTestCase("test_default_widget_size"))    suite.addTest(WidgetTestCase("test_widget_resize"))    return suiteif __name__ == "__main__":    runner = unittest.TextTestRunner()    runner.run(suite())

你可以将测试用例和测试套件的定义放在与他们要测试的代码相同的模块中(例如widget.py),但是放置测试代码有很多优点在一个单独的模块中,例如test_widget.py

  • 测试模块可以从命令行独立运行.
  • 测试代码可以更容易地与发货的代码分开。
  • 没有充分的理由改变测试代码以适应它测试的代码的诱惑力较小.
  • 测试代码应该比它测试的代码更频繁地修改.
  • 经过测试的代码可以更容易地重构.
  • 用C语言编写的模块的测试无论如何必须在单独的模块中,为什么不一致?
  • 如果测试策略发生变化,则无需更改使用旧的测试代码

重新使用旧的测试代码

有些用户会发现他们现有的测试代码需要来自unittest,而不需要转换旧的测试代码函数到TestCase子类

为此,unittest提供了一个FunctionTestCase类。这个TestCase的子类可以用来包装现有的测试功能。也可以提供设置和拆卸功能.

给出以下测试功能:

def testSomething():    something = makeSomething()    assert something.name is not None    # ...

可以创建如下的等效测试用例实例,可选设置和拆卸方法:

testcase = unittest.FunctionTestCase(testSomething,                                     setUp=makeSomethingDB,                                     tearDown=deleteSomethingDB)

注意

即使FunctionTestCase可用于快速将现有的测试基础转换为基于unittest的系统,也不推荐这种方法。花时间设置适当的TestCase子类将使未来的测试重构变得无比容易.

在某些情况下,现有的测试可能是使用doctest模块编写的。如果是这样的话,doctest提供一个DocTestSuite可自动构建的类unittest.TestSuite来自现有的实例doctest基于测试.

跳过测试和预期的失败

版本3.1.

Unittest支持跳过单个测试方法甚至整个类测试。此外,它支持将测试标记为“预期的失败”,这是一个被破坏并将失败的测试,但不应该被视为失败的TestResult.

跳过测试只是使用skip() 装饰器或其中一个条件变体.

基本跳过看起来像这样:

class MyTestCase(unittest.TestCase):    @unittest.skip("demonstrating skipping")    def test_nothing(self):        self.fail("shouldn"t happen")    @unittest.skipIf(mylib.__version__ < (1, 3),                     "not supported in this library version")    def test_format(self):        # Tests that work for only a certain version of the library.        pass    @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")    def test_windows_support(self):        # windows specific testing code        pass

这是以详细模式运行上面示例的输出:

test_format (__main__.MyTestCase) ... skipped "not supported in this library version"test_nothing (__main__.MyTestCase) ... skipped "demonstrating skipping"test_windows_support (__main__.MyTestCase) ... skipped "requires Windows"----------------------------------------------------------------------Ran 3 tests in 0.005sOK (skipped=3)

可以像方法一样跳过类:

@unittest.skip("showing class skipping")class MySkippedTestCase(unittest.TestCase):    def test_not_run(self):        pass

TestCase.setUp()也可以跳过测试。当需要设置的资源不可用时,这很有用.

预期的失败使用expectedFailure() decorator.

class ExpectedFailureTestCase(unittest.TestCase):    @unittest.expectedFailure    def test_fail(self):        self.assertEqual(1, 0, "broken")

通过制作一个调用skip()在测试时它想要跳过它。除非传递的对象具有某个属性,否则此装饰器跳过测试:

def skipUnlessHasattr(obj, attr):    if hasattr(obj, attr):        return lambda func: func    return unittest.skip("{!r} doesn"t have {!r}".format(obj, attr))

以下装饰器实现了测试跳过和预期的失败:

@unittest.skipreason

无条件地跳过装饰测试。reason应该说明为什么要跳过测试.

@unittest.skipIf (condition, reason)

如果condition是真的。

@unittest.skipUnlesscondition, reason

跳过装饰测试,除非condition是真的。

@unittest.expectedFailure

将测试标记为预期的失败。如果测试失败,将被认为是成功的。如果测试通过,将被视为失败.

exception unittest.SkipTest (reason )

提出这个异常是为了跳过测试.

通常你可以使用TestCase.skipTest()或其中一个跳过装饰器而不是直接提升它.

试验不会有setUp() 要么 tearDown()在他们周围跑来跑去。被骗的班级不会有setUpClass()要么 tearDownClass()run.Skipped模块没有setUpModule()要么 tearDownModule()跑。

使用子测试区分测试迭代

版本3.4.

当你的测试之间存在非常小的差异时,例如,通过一些参数,unittest允许你使用subTest()上下文管理器来区分它们在测试方法体内.

例如,以下测试:

class NumbersTest(unittest.TestCase):    def test_even(self):        """        Test that numbers between 0 and 5 are all even.        """        for i in range(0, 6):            with self.subTest(i=i):                self.assertEqual(i % 2, 0)

将产生以下输出:

======================================================================FAIL: test_even (__main__.NumbersTest) (i=1)----------------------------------------------------------------------Traceback (most recent call last):  File "subtests.py", line 32, in test_even    self.assertEqual(i % 2, 0)AssertionError: 1 != 0======================================================================FAIL: test_even (__main__.NumbersTest) (i=3)----------------------------------------------------------------------Traceback (most recent call last):  File "subtests.py", line 32, in test_even    self.assertEqual(i % 2, 0)AssertionError: 1 != 0======================================================================FAIL: test_even (__main__.NumbersTest) (i=5)----------------------------------------------------------------------Traceback (most recent call last):  File "subtests.py", line 32, in test_even    self.assertEqual(i % 2, 0)AssertionError: 1 != 0

如果不使用子测试,执行将在第一次失败后停止,并且错误将不太容易诊断,因为i的值不会显示:

======================================================================FAIL: test_even (__main__.NumbersTest)----------------------------------------------------------------------Traceback (most recent call last):  File "subtests.py", line 32, in test_even    self.assertEqual(i % 2, 0)AssertionError: 1 != 0

类和函数

本节深入介绍了unittest.

API的测试用例

class unittest.TestCasemethodName=”runTest”

TestCase类的实例代表了逻辑测试在unittest宇宙。此类旨在用作基类,具体测试由具体子类实现。该类实现了测试运行器所需的接口,以允许它驱动测试,以及测试代码可用于检查和报告各种故障的方法.

每个TestCase将运行一个基本方法:methodnamed methodName。在TestCase,你不会改变methodName也没有重新实现默认runTest()方法。

版本3.2:TestCase中的更改可以成功实例化而不提供methodName。这样可以更容易地从交互式解释器中试验TestCase .

TestCase实例提供了三组方法:一组用于运行测试,另一组用于测试实现以检查条件和报告失败,一些查询方法允许收集有关测试本身的信息.

第一组中的方法(运行测试)是:

setUp

调用准备测试夹具的方法。在调用测试方法之前立即调用它;除了AssertionErrorSkipTest之外,此方法引发的任何异常都将被视为错误而非测试失败。默认实现什么都不做.

tearDown ()

方法在调用测试方法后立即调用并记录结果。即使测试方法引发了异常,也会调用此方法,因此子类中的实现可能需要特别注意检查内部状态。除此之外的任何异常,除了AssertionErrorSkipTest之外,都会被认为是一个额外的错误而不是测试失败(从而增加了报告的错误总数)。只有在setUp()成功时才会调用此方法,无论测试方法的结果如何。默认实现无效.

setUpClass ( )

运行在单个类中的测试之前调用的类方法.setUpClass以类作为唯一参数调用,并且必须装饰为classmethod()

@classmethoddef setUpClass(cls):    ...

有关详细信息,请参阅类和模块夹具.

版本3.2.

tearDownClass

在单个类中测试后调用的类方法已经运行了tearDownClass被调用,类是唯一的参数,必须装饰为classmethod()

@classmethoddef tearDownClass(cls):    ...

有关详细信息,请参阅类和模块夹具.

新版本3.2.

run (result=None

运行测试,将结果收集到TestResult objectpassed为result。如果省略resultNone,则创建一个临时结果对象(通过调用defaultTestResult()方法)并使用。结果对象返回run()‘scaller.

只需调用TestCaseinstance.

在版本3.3中更改即可获得相同的效果:以前版本的run没有返回结果。没有打过一个实例.

skipTest (reason)

在测试方法中调用它或setUp()跳过当前测试。见跳过测试和预期的失败以获取更多信息.

新版本3.1.

subTestmsg=None, **params

返回一个上下文管理器,它执行封闭的代码块asubtestmsgparams是可选的,任意值,只要子测试失败就会显示,允许你清楚地识别它们.

测试用例可以包含任意数量的子测试声明,并且可以任意嵌套.

参见使用子测试区分测试迭代以获取更多信息.

版本3.4.

debug()

运行测试而不收集结果。这允许测试引发的异常传播给调用者,并可用于支持调试器下的运行测试.

TestCaseclass提供了几种断言方法来检查和报告失败。下表列出了最常用的方法(有关更多断言方法,请参阅下表):

方法 检查 @中的新内容
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)。注意msg关键字参数只有在使用时才能传递给assertRaises(),assertRaisesRegex(), assertWarns(), assertWarnsRegex()作为一个上下文管理员.

assertEqual (first, second, msg=None

测试firstsecond是平等的。如果数值不相等,则测试失败.

此外,如果firstsecond是完全相同的类型和一个oflist,tuple,dict,set,frozenset或str或子类注册的任何类型addTypeEqualityFunc()将调用特定于类型的相等函数以生成更有用的defaulterror消息(另请参阅类型特定方法列表)。

更改版本3.1:添加了类型特定的相等功能的自动调用.

在版本3.2中添加:assertMultiLineEqual()添加为比较字符串的默认类型相等功能.

assertNotEqualfirst, second, msg=None

测试firstsecond不相等。如果值docompare相等,测试将失败.

assertTrue (expr, msg=None )
assertFalse (expr, msg=None )

测试expr是真(或假).

请注意,这相当于bool(expr) is True而不是expris True(使用assertIs(expr, True)为后者)。当有更具体的方法可用时,也应该避免这种方法(例如assertEqual(a, b)而不是assertTrue(a == b)),因为它们在失败的情况下提供了更好的错误信息.

assertIs (first, second, msg=None )
assertIsNot (first, second, msg=None)

测试firstsecond评估(或不评估)相同的对象.

新版3.1.

assertIsNoneexpr, msg=None
assertIsNotNoneexpr, msg=None

测试expr是(或不是)None.

版本3.1.

assertInfirst, second, msg=None
assertNotInfirst, second, msg=None

测试first是(或不是)在second.

版本3.1.

assertIsInstanceobj, cls, msg=None
assertNotIsInstanceobj, cls, msg=None

测试obj是(或不是)cls的一个实例(可以是一个类或一个类的元组,由isinstance()支持)。要检查确切类型,请使用assertIs(type(obj), cls).

版本3.2.

也可以使用以下方法检查异常,警告和日志消息的产生:

方法 检查
assertRaises(exc, fun, *args, **kwds) fun(*args, **kwds)中的新增加exc  
assertRaisesRegex(exc, r, fun, *args, **kwds) fun(*args, **kwds)加注exc并且消息匹配正则表达式r 3.1
assertWarns(warn, fun, *args, **kwds) fun(*args, **kwds)提升warn 3.2
assertWarnsRegex(warn, r, fun, *args, **kwds) fun(*args, **kwds)提出warn并且消息与正则表达式匹配r 3.2
assertLogs(logger, level) with阻止logger登录level 3.4
assertRaises(exception, callable, *args, **kwds)
assertRaisesexception, *, msg=None

使用也传递给callable的任何位置或关键字参数调用assertRaises()时,测试是否引发异常。如果exception如果引发了另一个异常,则引发错误,如果没有引发异常则失败。要捕获任何一组异常,包含异常类的元组可以作为exception.

如果只给出了exception和可能的msg参数,则返回一个上下文管理器,以便测试中的代码可以写成内联而不是函数:

with self.assertRaises(SomeException):    do_something()

当用作上下文管理器时,assertRaises()接受附加关键字参数msg.

上下文管理器将把捕获的异常对象存储在其exception属性。如果故意对引发的异常执行附加检查,这可能很有用:

with self.assertRaises(SomeException) as cm:    do_something()the_exception = cm.exceptionself.assertEqual(the_exception.error_code, 3)

在3.1版中更改:添加了使用assertRaises()作为上下文管理器的功能.

版本3.2更改:添加了exception属性

更改版本3.3:添加了msg keyword参数用作上下文管理器时

assertRaisesRegexexception, 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
assertWarnswarning, *, msg=None

使用也传递给callable的任何位置或关键字参数调用assertWarns()时,测试是否触发警告。如果warning如果不是,则触发并失败。任何异常都是错误。为了捕获任何一组警告,包含警告类的元组可以传递为warnings.

如果只有warning和可能的msg给出了参数,返回一个上下文管理器,以便测试中的代码可以写成内联而不是函数:

with self.assertWarns(SomeWarning):    do_something()

当用作上下文管理器时,assertWarns()接受附加的关键字参数msg.

上下文管理器会将捕获的警告对象存储在其warning属性,以及触发filenamelineno如果打算执行额外的checkson警告捕获,这可能很有用:

with self.assertWarns(SomeWarning) as cm:    do_something()self.assertIn("myfile.py", cm.filename)self.assertEqual(320, cm.lineno)

无论调用它时警告过滤器如何,此方法都有效.

版本3.2.

改版3.3:添加了msg用作上下文管理器的关键字参数.

assertWarnsRegexwarning, regex, callable, *args, **kwds
assertWarnsRegexwarning, 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用作上下文管理器的关键字参数.

assertLogslogger=None, level=None

一个上下文管理器测试至少有一条消息记录在logger或其中一个子节点上,至少给出了level.

如果给出,logger应该是logging.Logger对象或str给出记录器的名称。默认是rootlogger,它将捕获所有消息.

如果给定,level应该是数字日志级别或等效字符串(例如"ERROR"要么logging.ERROR)。默认是logging.INFO.

如果with块匹配loggerlevel条件,否则失败.

上下文管理器返回的对象是一个记录助手,它记录匹配的日志消息。它有两个属性:

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) ab具有相同数量的相同元素,无论其顺序如何 3.2
assertAlmostEqualfirst, second, places=7, msg=None, delta=None
assertNotAlmostEqualfirst, second, places=7, msg=None, delta=None

通过计算差值来测试firstsecond大约(或不大约)相等,舍入到给定的十进制数places(默认为7),并与零比较。请注意,这些方法将值舍入为decimal places的给定数量(即round()函数),而不是significant digits.

如果delta提供而不是places那么firstsecond必须小于或等于(或大于)delta.

供应deltaplaces提起TypeError.

在版本3.2中更改:assertAlmostEqual()自动考虑比较相等的几乎相等的对象。assertNotAlmostEqual()如果对象比较相等则自动失败。添加了delta关键字参数.

assertGreater (first, second, msg=None )
assertGreaterEqual (first, second, msg=None )
assertLess (first, second, msg=None
assertLessEqualfirst, second, msg=None

测试first分别是&gt ;,&gt; =,&lt;或&lt; = than 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搜索匹配(或不匹配)text。如果失败,错误信息将包括模式和text(或者模式和意外匹配的text部分)。regex可能是一个正则表达式对象或一个包含一个适用于re.search().

的regularrexpression的字符串。版本3.1中的新增内容:名称assertRegexpMatches.

更改版本3.2:方法assertRegexpMatches()已重命名为assertRegex().

版本3.2中新增:assertNotRegex().

版本3.5中新增:name assertNotRegexpMatches是一个弃用的别名assertNotRegex().

assertCountEqualfirst, second, msg=None

测试序列first包含与second相同的元素,无论它们的顺序如何。如果没有,将生成列出序列之间差异的错误消息.

比较notfirst时,忽略了重复的元素second。它验证每个元素在两个序列中是否具有相同的计数。相当于:assertEqual(Counter(list(first)), Counter(list(second)))但也适用于不可用对象的序列.

新版本3.2.

assertEqual()方法调度对象的等式检查相同类型的不同类型的特定方法。这些方法已经针对大多数内置类型实现,但也可以使用addTypeEqualityFunc()

addTypeEqualityFunctypeobj, function

注册新方法由assertEqual()调用的特定于类型的方法来检查两个完全相同的对象typeobj(不是子类)compareequal。function必须采用两个位置参数和第三个msg = Nonekeyword参数,就像assertEqual()一样。它必须提高self.failureException(msg)当检测到前两个参数之间的不等式时 – 可能提供有用的信息并在错误消息中解释细节上的不等式

3.1版本中的新问题

自动使用的特定于类型的方法列表assertEqual()总结在下表中。请注意,通常没有必要直接调用这些方法.

方法 用来比较 新的
assertMultiLineEqual(a, b) 字符串 3.1
assertSequenceEqual(a, b) 序列 3.1
assertListEqual(a, b) 列表 3.1
assertTupleEqual(a, b) tatsles 3.1
assertSetEqual(a, b) sets or frozensets 3.1
assertDictEqual(a, b) dicts 3.1
assertMultiLineEqualfirst, second, msg=None

测试多行字符串first是否等于字符串second。当不等于两个字符串的差异时,突出显示差异将包含在错误消息中。默认情况下使用此方法时,将字符串与assertEqual().

比较新版本3.1.

assertSequenceEqual (first, second, msg=None, seq_type=None

测试两个序列是否相等。如果提供了seq_typefirstsecond都必须是seq_type或者会失败。如果序列不同,则构造错误信息,显示两者之间的差异.

这个方法不是由assertEqual()直接调用,而是用于实现assertListEqual()assertTupleEqual().

版本3.1.

assertListEqual(first, second, msg=None)
assertTupleEqual(first, second, msg=None)

新的两个列表或元组是等于。如果不是,则构造错误消息,仅显示两者之间的差异。如果其中一个参数的类型错误,也会引发错误。默认情况下使用这些方法比较列表或元组与assertEqual().

版本3.1中的新增.

assertSetEqualfirst, second, msg=None

测试两组是否相等。如果没有,则构造一个错误消息,列出这些集之间的差异。比较set或frozensets与assertEqual().

时,如果firstsecond中的任何一个没有set.difference()方法,则默认使用此方法.

版本3.1.

assertDictEqual (first, second, msg=None)

测试两个词典是否相等。如果不是,则构造一条错误消息,显示字典中的差异。默认情况下,此方法将用于比较字典和assertEqual().

版本3.1.

中的新内容最后TestCase提供了以下方法和属性:

failmsg=None

表示测试失败无条件地,带有msgNone的错误信息.

failureException

此类属性提供测试方法引发的异常。如果atest框架需要使用专门的异常,可能需要携带附加信息,它必须将此异常子类化,以便与框架“playfair”。该属性的初始值是AssertionError.

longMessage

此类属性确定将自定义失败消息作为msg参数传递给失败的assertXYY调用时发生的情况.True是默认值。在这种情况下,自定义消息被附加到标准失败消息的末尾。当设置为False时,自定义消息将替换标准消息.

通过在调用assert方法之前将实例属性self.longMessage赋值给TrueFalse,可以在各个测试方法中覆盖类设置.

在每次测试呼叫之前,类设置被重置.

版本3.1.

maxDiff

此属性控制assertmethods输出的diffs的最大长度,这些方法报告失败时的差异。它默认为80 * 8个字符。受此属性影响的断言方法是assertSequenceEqual()(包括委托给它的所有序列比较方法),assertDictEqual()assertMultiLineEqual().

设置maxDiffNone意味着没有最大长度的数据

版本3.2.

测试框架可以使用以下方法收集测试信息:

countTestCases

返回此测试对象表示的测试数。对于TestCase实例,这将始终是1.

defaultTestResult

返回应该用于此测试用例类的测试结果类的实例(如果没有提供其他结果实例)去run()方法).

对于TestCase实例,这将始终是TestResult的一个实例;TestCase的子类应该覆盖这一点.

id ( )

返回标识特定测试用例的字符串。这通常是测试方法的完整名称,包括模块和类名.

shortDescription

返回测试的描述,或None如果没有提供任何描述。此方法的默认实现返回测试方法的docstring的第一行(如果可用)或None.

在版本3.1中更改:在3.1中,这被更改为在存在docstring的情况下将测试名称添加到简短描述中。这导致与unittest扩展的兼容性问题,并添加测试名称被移动到TextTestResult在Python 3.2.

addCleanup (function, *args, **kwargs

tearDown()之后添加一个函数来清理测试期间使用的资源。函数将按照它们添加顺序的相反顺序调用(LIFO )。当它们被添加时,它们被调用任何参数和关键字参数传入addCleanup().

如果setUp()失败,意味着tearDown()没有被调用,那么添加的任何清理功能仍然会被调用.

新版3.1.

doCleanups ()

这种方法被无条件地称为之后tearDown(),orafter setUp()如果setUp()提出异常.

负责调用addCleanup()添加的所有清理功能。如果需要清理函数priortearDown()那么你可以调用doCleanups()yourself

doCleanups()一次一个地从一堆清理功能中弹出方法,所以可以随时调用它.

新版3.1.

class unittest.FunctionTestCase (testFunc, setUp=None, tearDown=None, description=None)

这个类实现TestCase接口whichallow测试运行器来驱动测试,但不提供测试代码可用于检查和报告错误的方法。这用于创建使用遗留测试代码的测试用例,允许它集成到基于unittest的测试框架中.

删除别名

由于历史原因,有些TestCase方法有一个或多个现已弃用的。下表列出了正确的名称及其弃用的别名:

方法名称 不推荐的别名 不推荐的别名
assertEqual() failUnlessEqual assertEquals
assertNotEqual() failIfEqual assertNotEquals
assertTrue() failUnless 断言_
assertFalse() failIf  
assertRaises() failUnlessRaises  
assertAlmostEqual() failUnlessAlmostEqual assertAlmostEquals
assertNotAlmostEqual() failIfAlmostEqual assertNotAlmostEquals
assertRegex()   assertRegexpMatches
assertNotRegex()   assertNotRegexpMatches
assertRaisesRegex()   assertRaisesRegexp

自版本后不推荐使用3.1:第二栏中列出的失败*别名.

自版本3.2:第三栏中列出的断言*别名.

自版本3.2:assertRegexpMatchesassertRaisesRegexp已重命名为assertRegex()assertRaisesRegex().

自版本3.5以来不推荐使用: assertNotRegexpMatches名称有利于assertNotRegex().

分组测试

class unittest.TestSuitetests=()

此类表示各个测试用例和测试套件的集合。该类提供了测试运行器所需的接口,以允许它在任何其他测试用例中运行。运行TestSuite实例与套件相同,单独运行每个测试.

如果给出tests,它必须是可迭代的单个测试用例或其他套件最初将用于构建套件。提供了其他方法,以便稍后将测试用例和套件添加到集合中.

TestSuite对象的行为与TestCase对象非常相似,除非它们实际上没有实现测试。相反,它们用于将测试聚合成应该一起运行的测试组。一些额外的方法可用于添加测试TestSuite实例的部分:

addTesttest

在套房里加一个TestCaseTestSuite.

addTests(tests)

TestCaseTestSuite实例的迭代中的所有测试添加到这个测试套件中.

这相当于迭代tests,调用addTest() foreach element.

TestSuiteTestCase

runresult

运行与此套件关联的测试,将结果收集到作为result传递的测试结果对象中。请注意,与TestCase.run(), TestSuite.run()不同,要求将结果对象传入.

debug (

运行与此套件关联的测试而不收集结果。这允许测试引发的异常传播到调用者,并可用于支持在调试器下运行测试.

countTestCases

返回此测试对象所代表的测试次数,包括所有个人测试和子测试.

__iter__

测试分组按TestSuite总是通过迭代访问。子类可以通过覆盖__iter__()。注意,在单个套件上可以多次调用此方法(例如,在计算测试或比较相等性时),因此在TestSuite.run()必须与每次调用迭代相同。在TestSuite.run()之后,调用者不应该依赖此方法返回的测试,除非调用者使用覆盖TestSuite._removeTestAtIndex()的asubclass来保存测试引用.

在版本3.2中更改:在早期版本中TestSuite直接通过迭代访问测试,所以重写__iter__()不足以提供测试.

版本3.4更改:在早期版本中TestSuite每个人都提到了TestCase之后TestSuite.run()。子类可以通过覆盖TestSuite._removeTestAtIndex().

TestSuite对象,run()方法是由TestRunner而不是最终用户测试工具调用的.

加载和运行测试

class unittest.TestLoader

TestLoaderclass用于从类和模块创建测试套件。通常,不需要创建此类的实例;unittest模块提供了一个可以共享的实例unittest.defaultTestLoader。但是,使用子类或实例可以自定义一些可配置的属性.

TestLoader对象具有以下属性:

errors

加载测试时遇到的非致命错误列表。在任何时候都不会被加载器重置。相关方法通过向调用者引发异常来发出致命错误信号。合成测试也表明非致命错误会在运行时引起原始错误.

版本3.5中的新功能

TestLoader对象有以下方法:

loadTestsFromTestCasetestCaseClass

返回包含在TestCase衍生testCaseClass.

getTestCaseNames()命名的每个方法创建一个测试用例实例。默认情况下,这些是使用test开始的方法名称。如果getTestCaseNames()返回nomethods,但是runTest()方法实现后,为该方法创建一个单独的测试用例.

loadTestsFromModule(module, pattern=None)

返回给定模块中包含的所有测试用例的套件。这个方法在module中搜索从TestCase派生的类,并为每个为类定义的测试方法创建一个类的实例.

注意

使用层次结构TestCase – 派生类可以很方便地共享fixture和helper函数,在基类上定义不打算直接实例化的testmethods并不适合这种方法。但是,当灯具不同并在子类中定义时,这样做会很有用.

如果一个模块提供了一个load_tests函数,它将被称为toload测试。这允许模块自定义测试加载。这是load_tests协议。pattern参数作为第三个参数传递给load_tests.

在版本3.2中更改:支持load_tests添加

更改版本3.5:无证的非官方的use_load_tests默认参数isdeprecated并被忽略,尽管它仍然被接受用于向后兼容性。该方法现在也接受一个只有关键字的参数pattern,它作为第三个参数传递给load_tests.

loadTestsFromName(name, module=None)

返回一个给出字符串说明符的所有测试用例的套件

说明符name是一个“点名”,可以解析为模块,测试用例类,测试方法测试用例类,TestSuite实例,或者是一个返回TestCaseTestSuite实例的可调用对象。这些检查按照此处列出的顺序进行;也就是说,可能的测试用例类的方法将被选为“测试用例类中的测试方法”,而不是“可调用对象”.

例如,如果你有一个模块SampleTests包含一个TestCase – 派生类SampleTestCase有三个testmethods(test_one(), test_two()test_three()),thepecpecifier "SampleTests.SampleTestCase"会导致这个方法可以返回一个运行所有三种测试方法的套件。使用说明符"SampleTests.SampleTestCase.test_two"会导致它返回一个只运行test_two()测试方法的测试套件。说明符可以指未导入的模块和包;它们将作为副作用进口.

该方法可选择解决name相对于给定的module.

在版本3.5中更改:如果 ImportError要么 AttributeError遍历时发生name那么一个合成测试会在运行时引发错误。这些错误包含在self.errors.

loadTestsFromNames(names, module=None)

累积的错误中。与loadTestsFromName(),但需要一系列名称而不是单个名称。返回值是一个测试套件,支持为每个名称定义的所有测试.

getTestCaseNames(testCaseClass)

返回testCaseClass中找到的方法名称的排序序列;这应该是TestCase.

discoverstart_dir, pattern=”test*.py”, top_level_dir=None

通过从指定的开始目录中递归到子目录中查找所有测试模块,并返回包含它们的TestSuite对象。只测试与pattern将被加载。(使用shell样式匹配。)只能加载可导入的模块名称(即validPython标识符).

所有测试模块必须可从项目的顶层导入。如果起始目录不是顶级目录,则必须单独指定顶级目录.

如果导入模块失败,例如由于语法错误,则会将其记录为单个错误,并且将继续发现。如果导入失败是由于SkipTest被引发时,它将被记录为跳过而不是错误.

如果找到包(包含名为__init__.py的文件的目录),将检查包的是否load_tests功能。如果存在,那么它将被称为package.load_tests(loader, tests, pattern)。测试发现需要注意确保一个包只在aninvocation期间检查一次测试,即使load_tests函数本身调用loader.discover.

如果load_tests存在,那么发现会not递入包装,load_tests负责加载​​包装中的所有测试.

故意不将模式存储为加载器属性,以便包可以继续自己发现。top_level_dir存储所以load_tests不需要将这个参数传递给loader.discover().

start_dir可以是虚线模块名称和目录.

新版本3.2.

更改版本3.4:模块提升SkipTest导入时记录为跳过,而不是错误。发现适用于命名空间包.Paths在导入之前进行排序,这样即使底层文件系统的排序不依赖于文件名,执行顺序也是一样的.

在版本3.5中改变:找到的包现在检查load_tests,不管它们的路径是否匹配pattern,因为包名不能与默认模式匹配.

//的以下属性TestLoader可以通过实例上的子类或赋值来配置:

testMethodPrefix

给出方法名称前缀的字符串,它将被解释为testmethods。默认值为"test".

这会影响getTestCaseNames()以及loadTestsFrom*()methods.

sortTestMethodsUsing

getTestCaseNames()loadTestsFrom*()方法中对它们进行排序时用于比较方法名称的功能

suiteClass

可调用对象,从测试列表构造测试套件。需要在结果对象上的Nomethods。默认值是​​TestSuite类。

这影响了所有loadTestsFrom*()方法。

testNamePatterns

测试方法必须匹配的Unix shell样式通配符测试名称模式列表,以包含在测试套件中(参见-v选项).

如果此属性不是None(默认值),要包含在测试套件中的所有测试方法必须与此列表中的一个模式匹配。请注意,匹配始终使用fnmatch.fnmatchcase()执行,因此不同于传递给-v选项,简单子串模式必须使用*通配符转换

这会影响所有loadTestsFrom*()方法.

新版本3.7.

class unittest.TestResult

该类用于编译有关哪些测试成功以及哪些测试失败的信息.

A TestResult object存储一组测试的结果。TestCaseTestSuite课程确保正确记录结果;测试作者不需要担心记录测试的结果.

建立在unittest之上的测试框架可能需要访问TestResult通过为报告目的运行一组测试而生成的对象;为此目的,TestResult方法返回TestRunner.run()实例.

TestResult在检查运行一组测试的结果时,实例具有以下属性:

errors

包含2元组TestCase实例和stringsholding格式化回溯。每个元组代表一个测试,它引起了一个异常的异常.

failures

一个包含2元组TestCase实例和stringsholding格式化回溯。每个元组代表一个测试,其中使用TestCase.assert*()方法显着地发出故障信息

skipped

包含2元组TestCase实例和字符串保留跳过测试的原因.

新版本3.1.

expectedFailures

包含2元组TestCase实例和stringsholding格式化回溯。每个元组代表测试用例的预期失败.

unexpectedSuccesses

包含TestCase被标记为预期失败但是成功的实例

shouldStop

设置为True当执行测试时应该停止stop().

testsRun

到目前为止测试的总数.

buffer

如果设置为true,sys.stdoutsys.stderr将被缓冲在startTest()stopTest()被调用之间。收集的输出只会回显到真实的sys.stdoutsys.stderr如果测试失败或错误。任何输出也附加到故障/错误消息.

新版本3.2.

failfast

如果设置为真stop()将在第一次失败或错误时调用,停止测试运​​行.

新版本3.2.

tb_locals

如果设置为true,则局部变量将显示在tracebacks.

3.5版本中的新功能

wasSuccessful// (

返回True如果到目前为止所有测试都已通过,否则返回False.

版本3.4更改:返回False如果有unexpectedSuccesses来自用expectedFailure()decorator.

stop

可以通过将shouldStop属性设置为True.TestRunner对象应该尊重这个标志,并且在没有任何额外的测试的情况下返回.

例如,这个功能被TextTestRunner当用户通过键盘发出中断信号时停止测试框架的类。提供TestRunner实现的交互式工具可以以类似的方式使用它.

以下方法TestResultclass用于维护内部数据结构,可以在子类中扩展以支持其他报告要求。这对于在运行测试时支持交互式报告的构建工具特别有用.

startTesttest

当测试用例test即将运行时调用

stopTest (test)

在测试用例test执行后调用,无论结果如何.

startTestRun()

在执行任何测试之前调用一次.

新版本3.1.

stopTestRun ()

在所有测试执行后调用一次

版本3.1.

addError(test, err)

新的测试用例test引发意外的异常。errsys.exc_info()(type, value,traceback).

返回的格式的元组件。默认实现将一个元组(test, formatted_err)附加到实例的errors属性,其中formatted_err是从err.

addFailuretest, err

派生的格式化回溯,当测试用例test表示失败时调用。errsys.exc_info()(type, value, traceback).

默认实现将一个元组(test, formatted_err)附加到实例的failures属性,其中formatted_err是从err.

addSuccesstest)派生的格式化回溯

当测试用例test成功时调用

默认实现什么都不做.

addSkip(test, reason)

在测试用例test被忽略时调用。reason是测试跳过的原因.

默认实现附加一个元组(test, reason)到实例的skipped属性。

addExpectedFailuretest, err

在测试用例时调用test失败,但标有expectedFailure()decorator.

默认实现附加一个元组(test, formatted_err)到实例的expectedFailures属性,formatted_err是一个源自err.

addUnexpectedSuccesstest

在测试用例时调用testexpectedFailure()装饰器标记,但是成功了

默认实现将测试附加到实例的unexpectedSuccesses属性

addSubTesttest, subtest, outcome/)

当子测试结束时调用。test是与测试方法相对应的测试用例。subtest是一个定制的TestCase实例描述子测试

如果outcomeNone,分测试成功了。否则,它失败了,其中outcome是由sys.exc_info()(type, value, traceback).

当结果为asccess时,默认实现不执行任何操作,并将子测试失败记录为正常故障.

版本3.4.

class unittest.TextTestResultstream, descriptions, verbosity

的具体实现TestResult用于TextTestRunner.

版本3.2中的新功能:此课程以前被命名为_TextTestResult。旧名stillexists作为别名,但已被弃用.

unittest.defaultTestLoader

的实例TestLoader要分享的课程。如果需要对TestLoader进行nocustomization,可以使用这个实例而不是重复创建新实例.

class unittest.TextTestRunner (stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False )

将结果输出到流的基本测试运行器实现。如果streamNone,则默认为sys.stderr用作输出流。这个类有一些可配置的参数,但基本上非常简单。运行测试套件的图形应用程序应该提供替代实现。这样的实现应该接受**kwargs作为在将功能添加到unittest时构建runners的接口改变

默认这个运行器显示DeprecationWarning,PendingDeprecationWarning, ResourceWarningImportWarning即使它们是默认被忽略。由引起的弃用警告弃用了unittestmethods 也是特殊的,当警告过滤器是"default""always"时,它们只出现一次模块,以避免过多的警告信息。可以使用Python的-Wd-Wa选项覆盖此行为(请参阅警告控制)并将warnings留给None.

在版本3.2中更改:添加了warnings参数

在版本3.2中更改:默认流设置为sys.stderr在实例化时间大于导入时间

更改版本3.5:添加了tb_locals参数.

_makeResult (

这个方法返回TestResult使用的run()的实例。它不是要直接调用,而是可以重写的子类来提供自定义TestResult.

_makeResult()实例化类或者callable在TextTestRunner构造函数中作为resultclass参数传递。如果没有提供TextTestResult,则默认为resultclass。结果类用以下参数实例化:

stream, descriptions, verbosity
runtest

这个method是 TextTestRunner 。这个方法需要TestSuiteTestCase实例。TestResult是通过调用_makeResult()然后运行测试并将结果打印到stdout。

unittest.mainmodule=”__main__”, defaultTest=None, argv=None, testRunner=None, testLoader=unittest.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None

module并运行它们;这主要是为了使测试模块可以方便地执行。此函数的最简单用途是在测试脚本的末尾包含以下行:

if __name__ == "__main__":    unittest.main()

你可以通过传递verbosityargument来运行带有更详细信息的测试:

if __name__ == "__main__":    unittest.main(verbosity=2)

defaultTest如果没有通过argv指定测试名称,则参数可以是单个测试的名称,也可以是要运行的测试名称的无法使用的参数。如果没有指定或None并且没有通过argv,在module中找到的所有测试都运行了

argv参数可以是传递给程序的选项列表,其中第一个元素是程序名称。如果没有指定或Nonesys.argv使用了

testRunner参数可以是测试运行器类,也可以是已创建的实例。默认情况下main调用sys.exit()用退出代码表示测试成功或失败.

testLoader参数必须是TestLoader instance,默认为defaultTestLoader.

main支持通过传入参数exit=False从交互式解释器中使用。这将在标准输出上显示结果而不调用sys.exit()

>>> from unittest import main>>> main(module="test_module", exit=False)

failfast, catchbreakbuffer参数与同名命令行选项具有相同的效果.

warnings参数指定运行测试时应该使用的警告过滤器。如果没有指定,它将保持None如果-W选项被传递给 python (参见警告控制),否则将设置为"default".

调用main实际上返回TestProgram类的实例。这样可​​以将测试结果存储为result属性

更改版本3.1: exit参数已添加.

在版本3.2中更改:添加了verbosity, failfast, catchbreak, bufferwarnings参数

在版本3.4中更改: defaultTest参数被更改为也接受一个可迭代的测试名称.

load_tests协议

版本3.2.

模块或包可以通过实现一个名为load_tests.

如果测试模块定义load_tests它会被TestLoader.loadTestsFromModule()使用以下参数:

load_tests(loader, standard_tests, pattern)

其中pattern直接从loadTestsFromModule传递。它默认为None.

它应该返回TestSuite.

loaderTestLoader正在装载的实例standard_tests是默认情况下从模块加载的测试。测试模块通常只想在标准测试集中添加或删除测试。第三个参数在加载包作为测试发现的一部分时使用.

从一组特定的load_tests类加载测试的典型TestCase函数可能如下所示:

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.)

收集的测试因为模式被传递到load_tests包是免费的继续(并可能修改)测试发现。测试包的“无所事事”load_tests功能如下所示:

def load_tests(loader, standard_tests, 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中更改:发现不再检查包名称是否匹配pattern由于包名称与默认模式匹配的不可能性

类和模块夹具

类和模块级夹具在TestSuite。当测试套件遇到来自新类的测试时tearDownClass()从上一个类(如果有的话)调用,然后从新类调用setUpClass()

同样,如果测试来自与之前测试不同的模块,那么tearDownModule从上一个模块运行,然后setUpModule来自新模块

经过所有测试后,最终tearDownClasstearDownModule跑了

请注意,共享装置不能很好地利用testparallelization等[潜在]功能,并且会破坏测试隔离。它们应该小心使用.

unittest测试加载器创建的测试的默认顺序是将来自相同模块和类的测试分组在一起。这将导致setUpClass / setUpModule(等)每个类和模块只调用一次。如果您将订单随机化,以便来自不同模块和类的测试彼此相邻,那么这些共享夹具功能可能会在单次测试运行中多次出现.

共享装置不适用于具有非标准订购的套件。对于不希望支持共享夹具的框架,仍然存在BaseTestSuite

如果在其中一个共享夹具功能期间引发任何异常,则将测试报告为错误。因为没有相应的测试实例,所以创建了_ErrorHolder对象(具有与TestCase相同的接口)来表示错误。如果你只是使用标准的unittest测试运行器,那么这个细节并不重要,但是如果你是一个框架作者它可能是相关的

setUpClass和tearDownClass

这些必须作为类方法实现:

import unittestclass Test(unittest.TestCase):    @classmethod    def setUpClass(cls):        cls._connection = createExpensiveConnectionObject()    @classmethod    def tearDownClass(cls):        cls._connection.destroy()

如果你想在基类上调用setUpClasstearDownClass那么你必须自己打电话给他们。TestCase中的实现是空的.

如果在setUpClass期间出现异常,那么类中的测试不会运行且tearDownClass不会运行。跳过的课程不会有setUpClasstearDownClass跑。如果例外是SkipTest异常然后该类将被报告为已跳过而不是作为错误

setUpModuletearDownModule

这些应该实现为函数:

def setUpModule():    createConnection()def tearDownModule():    closeConnection()

如果引发异常a setUpModule然后将运行模块中的所有测试,并且tearDownModule将不会运行。如果异常是SkipTest异常,那么模块将被报告为已跳过而不是错误.

信号处理

版本3.2中的新功能.

单元测试-c/--catch命令行选项,以及catchbreak参数unittest.main(),在测试运行期间提供对控制-C的更友好的处理。启用catch breakbehavior后,control-C将允许当前正在运行的测试完成,然后测试运行将结束并报告所有结果。一个secondcontrol-c将以通常的方式引发KeyboardInterrupt

control-c处理信号处理程序试图保持与安装自己的signal.SIGINT处理程序的代码orte兼容。如果unittest处理程序被调用但是isn’t已安装的signal.SIGINT处理程序,即。它已被被测系统替换并委托给它,然后它调用默认处理程序。这通常是代码替换已安装的处理程序并委托给它的预期行为。对于需要unittest control-c处理禁用的个别测试,可以使用removeHandler()装饰器.

框架作者有一些实用功能可以在测试中启用控制功能frameworks.

unittest.installHandler ()

安装control-c处理程序。当收到signal.SIGINT时(通常是响应用户按下control-c)所有注册的结果都有stop()被叫

unittest.registerResult// (result

注册TestResult对象以进行control-c处理。注册aresult商店是一个弱的参考,所以它不会阻止收集垃圾的结果.

注册TestResult如果没有启用control-chandling,对象没有副作用,因此测试框架可以无条件地注册它们创建的结果,无论是否启用处理.

unittest.removeResult (result )

删除已注册的结果。一旦结果被删除,那么stop()将不再被调用该结果对象响应一个control-c.

unittest.removeHandler(function=None)

在没有参数的情况下调用此函数会删除已安装的control-c处理程序。此函数也可以用作测试decoratorto在执行测试时临时删除处理程序:

@unittest.removeHandlerdef test_signal_handling(self):    ...