test — Python 回归测试包

注意

test 包仅供 Python 内部使用。它的文档仅为 Python 的核心开发人员提供便利。不鼓励在 Python 标准库之外使用此包,因为此处提到的代码可能会在 Python 版本之间更改或删除,恕不另行通知。


test 包包含 Python 的所有回归测试,以及模块 test.supporttest.regrtesttest.support 用于增强您的测试,而 test.regrtest 则驱动测试套件。

test 包中名称以 test_ 开头的每个模块都是特定模块或功能的测试套件。所有新测试都应使用 unittestdoctest 模块编写。一些较旧的测试是使用“传统”测试风格编写的,该风格比较打印到 sys.stdout 的输出;这种测试风格被认为是已弃用的。

另请参阅

模块 unittest

编写 PyUnit 回归测试。

模块 doctest

嵌入在文档字符串中的测试。

test 包编写单元测试

首选使用 unittest 模块的测试遵循一些准则。其中之一是将测试模块的名称以 test_ 开头,并以被测试的模块的名称结尾。测试模块中的测试方法应以 test_ 开头,并以描述该方法正在测试的内容结尾。这是必需的,以便测试驱动程序将这些方法识别为测试方法。此外,不应包含该方法的文档字符串。应使用注释(例如 # 测试函数仅返回 True False)来为测试方法提供文档。这样做是因为如果存在文档字符串,它们会被打印出来,从而不会说明正在运行的测试。

通常使用基本的样板代码

import unittest
from test import support

class MyTestCase1(unittest.TestCase):

    # Only use setUp() and tearDown() if necessary

    def setUp(self):
        ... code to execute in preparation for tests ...

    def tearDown(self):
        ... code to execute to clean up after tests ...

    def test_feature_one(self):
        # Test feature one.
        ... testing code ...

    def test_feature_two(self):
        # Test feature two.
        ... testing code ...

    ... more test methods ...

class MyTestCase2(unittest.TestCase):
    ... same structure as MyTestCase1 ...

... more test classes ...

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

此代码模式允许测试套件由 test.regrtest 运行,它本身作为一个支持 unittest CLI 的脚本,或者通过 python -m unittest CLI 运行。

回归测试的目标是尝试破坏代码。这导致需要遵循一些准则

  • 测试套件应覆盖所有类、函数和常量。这不仅包括要呈现给外部的外部 API,还包括“私有”代码。

  • 首选白盒测试(在编写测试时检查被测代码)。黑盒测试(仅测试已发布的用用户界面)不足以确保所有边界和边缘情况都经过测试。

  • 确保测试所有可能的值,包括无效值。这不仅确保所有有效值都是可接受的,而且确保不正确的值得到正确处理。

  • 尽可能穷尽代码路径。测试分支发生的地方,从而调整输入以确保尽可能多地执行不同的代码路径。

  • 为被测代码中发现的任何错误添加显式测试。这将确保如果将来代码发生更改,错误不会再次出现。

  • 确保在测试后进行清理(例如关闭和删除所有临时文件)。

  • 如果测试依赖于操作系统的特定条件,则在尝试测试之前验证该条件是否已存在。

  • 尽可能少地导入模块,并尽快导入。这最大限度地减少了测试的外部依赖性,也最大限度地减少了导入模块的副作用可能造成的异常行为。

  • 尽量最大化代码重用。有时,测试的变化可能只在于使用的输入类型。通过使用指定输入的类对基本测试类进行子类化,从而尽量减少代码重复。

    class TestFuncAcceptsSequencesMixin:
    
        func = mySuperWhammyFunction
    
        def test_func(self):
            self.func(self.arg)
    
    class AcceptLists(TestFuncAcceptsSequencesMixin, unittest.TestCase):
        arg = [1, 2, 3]
    
    class AcceptStrings(TestFuncAcceptsSequencesMixin, unittest.TestCase):
        arg = 'abc'
    
    class AcceptTuples(TestFuncAcceptsSequencesMixin, unittest.TestCase):
        arg = (1, 2, 3)
    

    当使用此模式时,请记住,所有继承自 unittest.TestCase 的类都作为测试运行。上面的示例中的 TestFuncAcceptsSequencesMixin 类没有任何数据,因此不能单独运行,因此它不继承自 unittest.TestCase

另请参阅

测试驱动开发

Kent Beck 关于在编写代码之前编写测试的一本书。

使用命令行界面运行测试

由于 -m 选项,test 包可以作为脚本运行来驱动 Python 的回归测试套件:python -m test。在底层,它使用 test.regrtest;以前 Python 版本中使用的调用 python -m test.regrtest 仍然有效。单独运行脚本会自动启动运行 test 包中的所有回归测试。它通过查找包中名称以 test_ 开头的所有模块,导入它们,并执行函数 test_main() (如果存在)或通过 unittest.TestLoader.loadTestsFromModule 加载测试(如果 test_main 不存在)。要执行的测试名称也可以传递给脚本。指定单个回归测试 (python -m test test_spam) 将最小化输出,并且只打印测试是通过还是失败。

直接运行 test 允许设置可供测试使用的资源。您可以使用 -u 命令行选项来执行此操作。将 all 指定为 -u 选项的值将启用所有可能的资源:python -m test -uall。如果需要除一个资源之外的所有资源(更常见的情况),可以在 all 之后列出以逗号分隔的不需要的资源列表。命令 python -m test -uall,-audio,-largefile 将运行 test,其中包含除 audiolargefile 资源之外的所有资源。有关所有资源和更多命令行选项的列表,请运行 python -m test -h

执行回归测试的其他一些方法取决于执行测试的平台。在 Unix 上,您可以在构建 Python 的顶层目录中运行 make test。在 Windows 上,从您的 PCbuild 目录执行 rt.bat 将运行所有回归测试。

test.support — Python 测试套件的实用工具

test.support 模块为 Python 的回归测试套件提供了支持。

注意

test.support 不是公共模块。此处记录它是为了帮助 Python 开发人员编写测试。此模块的 API 可能会在版本之间更改,而无需考虑向后兼容性。

此模块定义以下异常

exception test.support.TestFailed

当测试失败时引发的异常。此异常已弃用,赞成使用基于 unittest 的测试和 unittest.TestCase 的断言方法。

exception test.support.ResourceDenied

unittest.SkipTest 的子类。当资源(例如网络连接)不可用时引发。由 requires() 函数引发。

test.support 模块定义以下常量

test.support.verbose

启用详细输出时为 True。当需要有关正在运行的测试的更多详细信息时,应检查此项。verbosetest.regrtest 设置。

test.support.is_jython

如果正在运行的解释器是 Jython,则为 True

test.support.is_android

如果系统是 Android,则为 True

test.support.unix_shell

如果不在 Windows 上,则为 shell 的路径;否则为 None

test.support.LOOPBACK_TIMEOUT

使用在网络本地环回接口(如 127.0.0.1)上侦听的网络服务器进行测试的超时时间(以秒为单位)。

超时时间足够长,可以防止测试失败:它考虑到客户端和服务器可以在不同的线程甚至不同的进程中运行。

超时时间应足够长,以允许 connect()recv()send() 方法的 socket.socket 方法。

其默认值为 5 秒。

另请参阅 INTERNET_TIMEOUT

test.support.INTERNET_TIMEOUT

向 Internet 发送网络请求的超时时间(以秒为单位)。

超时时间足够短,可以防止测试在因任何原因阻止 Internet 请求时等待太长时间。

通常,使用 INTERNET_TIMEOUT 的超时不应将测试标记为失败,而是应跳过测试:请参阅 transient_internet()

其默认值为 1 分钟。

另请参阅 LOOPBACK_TIMEOUT

test.support.SHORT_TIMEOUT

如果测试花费“太长时间”,则将测试标记为失败的超时时间(以秒为单位)。

超时值取决于 regrtest --timeout 命令行选项。

如果使用 SHORT_TIMEOUT 的测试开始在较慢的构建机器人上随机失败,请改用 LONG_TIMEOUT

其默认值为 30 秒。

test.support.LONG_TIMEOUT

用于检测测试何时挂起的超时时间(以秒为单位)。

它足够长,可以降低在最慢的 Python 构建机器人上测试失败的风险。 如果测试花费“太长时间”,则不应使用它将测试标记为失败。 超时值取决于 regrtest --timeout 命令行选项。

其默认值为 5 分钟。

另请参阅 LOOPBACK_TIMEOUTINTERNET_TIMEOUTSHORT_TIMEOUT

test.support.PGO

当测试对于 PGO 无用时,设置此项以便跳过测试。

test.support.PIPE_MAX_SIZE

一个常量,它可能大于底层操作系统管道缓冲区大小,以使写入阻塞。

test.support.Py_DEBUG

如果 Python 是使用定义了 Py_DEBUG 宏构建的,即如果 Python 是以调试模式构建的,则为 True

3.12 版本中新增。

test.support.SOCK_MAX_SIZE

一个常量,它可能大于底层操作系统套接字缓冲区大小,以使写入阻塞。

test.support.TEST_SUPPORT_DIR

设置为包含 test.support 的顶层目录。

test.support.TEST_HOME_DIR

设置为测试包的顶层目录。

test.support.TEST_DATA_DIR

设置为测试包中的 data 目录。

test.support.MAX_Py_ssize_t

对于大内存测试,设置为 sys.maxsize

test.support.max_memuse

set_memlimit() 设置为大内存测试的内存限制。受 MAX_Py_ssize_t 限制。

test.support.real_max_memuse

set_memlimit() 设置为大内存测试的内存限制。不受 MAX_Py_ssize_t 限制。

test.support.MISSING_C_DOCSTRINGS

如果 Python 是在没有文档字符串的情况下构建的(未定义 WITH_DOC_STRINGS 宏),则设置为 True。请参阅 configure --without-doc-strings 选项。

另请参阅 HAVE_DOCSTRINGS 变量。

test.support.HAVE_DOCSTRINGS

如果函数文档字符串可用,则设置为 True。请参阅 python -OO 选项,该选项会删除 Python 中实现的函数的文档字符串。

另请参阅 MISSING_C_DOCSTRINGS 变量。

test.support.TEST_HTTP_URL

定义网络测试的专用 HTTP 服务器的 URL。

test.support.ALWAYS_EQ

一个与任何事物都相等的对象。 用于测试混合类型比较。

test.support.NEVER_EQ

一个与任何事物都不相等的对象(甚至与 ALWAYS_EQ 也不相等)。 用于测试混合类型比较。

test.support.LARGEST

一个比任何事物都大的对象(除了它本身)。 用于测试混合类型比较。

test.support.SMALLEST

一个比任何事物都小的对象(除了它本身)。 用于测试混合类型比较。

test.support 模块定义了以下函数

test.support.busy_retry(timeout, err_msg=None, /, *, error=True)

运行循环体,直到 break 停止循环。

timeout 秒后,如果 error 为 true,则引发 AssertionError,如果 error 为 false,则仅停止循环。

示例

for _ in support.busy_retry(support.SHORT_TIMEOUT):
    if check():
        break

error=False 用法示例

for _ in support.busy_retry(support.SHORT_TIMEOUT, error=False):
    if check():
        break
else:
    raise RuntimeError('my custom error')
test.support.sleeping_retry(timeout, err_msg=None, /, *, init_delay=0.010, max_delay=1.0, error=True)

应用指数退避的等待策略。

运行循环体,直到 break 停止循环。 在每次循环迭代时休眠,但不在第一次迭代时休眠。 休眠延迟在每次迭代时加倍(最多 max_delay 秒)。

有关参数用法,请参阅 busy_retry() 文档。

在 SHORT_TIMEOUT 秒后引发异常的示例

for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
    if check():
        break

error=False 用法示例

for _ in support.sleeping_retry(support.SHORT_TIMEOUT, error=False):
    if check():
        break
else:
    raise RuntimeError('my custom error')
test.support.is_resource_enabled(resource)

如果resource已启用且可用,则返回 True。 只有在 test.regrtest 执行测试时,才会设置可用资源的列表。

test.support.python_is_optimized()

如果 Python 在构建时未使用 -O0-Og,则返回 True

test.support.with_pymalloc()

返回 _testcapi.WITH_PYMALLOC

test.support.requires(resource, msg=None)

如果 resource 不可用,则引发 ResourceDenied。 如果引发异常,msgResourceDenied 的参数。 如果由 __name__'__main__' 的函数调用,则始终返回 True。当测试由 test.regrtest 执行时使用。

test.support.sortdict(dict)

返回键已排序的 dict 的 repr。

test.support.findfile(filename, subdir=None)

返回名为 filename 的文件的路径。 如果未找到匹配项,则返回 filename。 这不等于失败,因为它可能是文件的路径。

设置 subdir 表示要用于查找文件的相对路径,而不是直接在路径目录中查找。

test.support.get_pagesize()

获取页面的大小(以字节为单位)。

3.12 版本中新增。

test.support.setswitchinterval(interval)

sys.setswitchinterval() 设置为给定的 interval。 为 Android 系统定义最小间隔,以防止系统挂起。

test.support.check_impl_detail(**guards)

使用此检查来保护 CPython 的特定于实现的测试,或仅在由参数保护的实现上运行它们。 此函数根据主机平台返回 TrueFalse。 用法示例

check_impl_detail()               # Only on CPython (default).
check_impl_detail(jython=True)    # Only on Jython.
check_impl_detail(cpython=False)  # Everywhere except CPython.
test.support.set_memlimit(limit)

为大内存测试设置 max_memusereal_max_memuse 的值。

test.support.record_original_stdout(stdout)

存储来自 stdout 的值。 它旨在保存 regrtest 开始时的标准输出。

test.support.get_original_stdout()

返回由 record_original_stdout() 设置的原始标准输出,如果未设置,则返回 sys.stdout

test.support.args_from_interpreter_flags()

返回一个命令行参数列表,用于重现 sys.flagssys.warnoptions 中的当前设置。

test.support.optim_args_from_interpreter_flags()

返回一个命令行参数列表,用于重现 sys.flags 中的当前优化设置。

test.support.captured_stdin()
test.support.captured_stdout()
test.support.captured_stderr()

一个上下文管理器,它临时将命名流替换为 io.StringIO 对象。

输出流的用法示例

with captured_stdout() as stdout, captured_stderr() as stderr:
    print("hello")
    print("error", file=sys.stderr)
assert stdout.getvalue() == "hello\n"
assert stderr.getvalue() == "error\n"

输入流的用法示例

with captured_stdin() as stdin:
    stdin.write('hello\n')
    stdin.seek(0)
    # call test code that consumes from sys.stdin
    captured = input()
self.assertEqual(captured, "hello")
test.support.disable_faulthandler()

一个上下文管理器,临时禁用 faulthandler

test.support.gc_collect()

强制尽可能多地收集对象。 这是必需的,因为垃圾回收器不保证及时释放。 这意味着 __del__ 方法可能会比预期的时间晚调用,并且弱引用可能会比预期的时间长地保持活动状态。

test.support.disable_gc()

一个上下文管理器,在进入时禁用垃圾回收器。 退出时,垃圾回收器将恢复到其先前的状态。

test.support.swap_attr(obj, attr, new_val)

用于将属性与新对象交换的上下文管理器。

用法

with swap_attr(obj, "attr", 5):
    ...

这将在 with 代码块的持续时间内将 obj.attr 设置为 5,并在代码块末尾恢复旧值。 如果 obj 上不存在 attr,它将被创建,然后在代码块末尾删除。

旧值(如果不存在,则为 None)将分配给“as”子句的目标(如果有)。

test.support.swap_item(obj, attr, new_val)

用于将项与新对象交换的上下文管理器。

用法

with swap_item(obj, "item", 5):
    ...

这将在 with 代码块的持续时间内将 obj["item"] 设置为 5,并在代码块结束时恢复旧值。如果 itemobj 上不存在,则会创建它,然后在代码块结束时删除它。

旧值(如果不存在,则为 None)将分配给“as”子句的目标(如果有)。

test.support.flush_std_streams()

调用 sys.stdout 上的 flush() 方法,然后再调用 sys.stderr 上的 flush() 方法。它可用于确保在写入 stderr 之前日志顺序是一致的。

3.11 版本中新增。

test.support.print_warning(msg)

将警告打印到 sys.__stderr__。将消息格式化为: f"Warning -- {msg}"。如果 msg 由多行组成,则在每行前面添加 "Warning -- " 前缀。

3.9 版本中新增。

test.support.wait_process(pid, *, exitcode, timeout=None)

等待进程 pid 完成,并检查进程退出代码是否为 exitcode

如果进程退出代码不等于 exitcode,则引发 AssertionError

如果进程运行时间超过 timeout 秒(默认为 SHORT_TIMEOUT),则终止该进程并引发 AssertionError。超时功能在 Windows 上不可用。

3.9 版本中新增。

test.support.calcobjsize(fmt)

返回 PyObject 的大小,其结构成员由 fmt 定义。返回的值包括 Python 对象头的大小和对齐方式。

test.support.calcvobjsize(fmt)

返回 PyVarObject 的大小,其结构成员由 fmt 定义。返回的值包括 Python 对象头的大小和对齐方式。

test.support.checksizeof(test, o, size)

对于测试用例 test,断言 osys.getsizeof 加上 GC 头部大小等于 size

@test.support.anticipate_failure(condition)

一个装饰器,用于有条件地使用 unittest.expectedFailure() 标记测试。任何使用此装饰器的地方都应附带一条注释,以标识相关的跟踪器问题。

test.support.system_must_validate_cert(f)

一个装饰器,在 TLS 证书验证失败时跳过被装饰的测试。

@test.support.run_with_locale(catstr, *locales)

一个装饰器,用于在不同的区域设置中运行函数,并在完成后正确重置它。catstr 是区域设置类别,以字符串形式表示(例如 "LC_ALL")。将按顺序尝试传入的 locales,并将使用第一个有效的区域设置。

@test.support.run_with_tz(tz)

一个装饰器,用于在特定的时区中运行函数,并在完成后正确重置它。

@test.support.requires_freebsd_version(*min_version)

在 FreeBSD 上运行测试时,用于设置最低版本的装饰器。如果 FreeBSD 版本小于最低版本,则跳过测试。

@test.support.requires_linux_version(*min_version)

在 Linux 上运行测试时,用于设置最低版本的装饰器。如果 Linux 版本小于最低版本,则跳过测试。

@test.support.requires_mac_version(*min_version)

在 macOS 上运行测试时,用于设置最低版本的装饰器。如果 macOS 版本小于最低版本,则跳过测试。

@test.support.requires_gil_enabled

一个装饰器,用于在自由线程构建上跳过测试。如果 GIL 被禁用,则跳过测试。

@test.support.requires_IEEE_754

一个装饰器,用于在非 IEEE 754 平台上跳过测试。

@test.support.requires_zlib

一个装饰器,如果 zlib 不存在,则跳过测试。

@test.support.requires_gzip

一个装饰器,如果 gzip 不存在,则跳过测试。

@test.support.requires_bz2

一个装饰器,如果 bz2 不存在,则跳过测试。

@test.support.requires_lzma

一个装饰器,如果 lzma 不存在,则跳过测试。

@test.support.requires_resource(resource)

一个装饰器,如果 resource 不可用,则跳过测试。

@test.support.requires_docstrings

一个装饰器,仅在 HAVE_DOCSTRINGS 时运行测试。

@test.support.requires_limited_api

一个装饰器,仅在 有限 C API 可用时运行测试。

@test.support.cpython_only

仅适用于 CPython 的测试装饰器。

@test.support.impl_detail(msg=None, **guards)

用于在 guards 上调用 check_impl_detail() 的装饰器。如果返回 False,则使用 msg 作为跳过测试的原因。

@test.support.no_tracing

在测试期间临时关闭跟踪的装饰器。

@test.support.refcount_test

用于涉及引用计数的测试的装饰器。如果测试不是由 CPython 运行的,则装饰器不会运行测试。在测试期间,任何跟踪函数都会被取消设置,以防止跟踪函数导致意外的引用计数。

@test.support.bigmemtest(size, memuse, dry_run=True)

用于 bigmem 测试的装饰器。

size 是测试请求的大小(以任意、测试解释的单位表示)。memuse 是测试的每个单位的字节数,或其良好估计值。例如,一个需要两个 4 GiB 字节缓冲区的测试可以用 @bigmemtest(size=_4G, memuse=2) 进行装饰。

size 参数通常作为额外的参数传递给被装饰的测试方法。如果 dry_runTrue,则传递给测试方法的值可能小于请求的值。如果 dry_runFalse,则表示在未指定 -M 时,测试不支持虚拟运行。

@test.support.bigaddrspacetest

用于填充地址空间的测试的装饰器。

test.support.check_syntax_error(testcase, statement, errtext='', *, lineno=None, offset=None)

通过尝试编译 statement 来测试 statement 中的语法错误。testcase 是测试的 unittest 实例。errtext 是应该与引发的 SyntaxError 的字符串表示形式匹配的正则表达式。如果 lineno 不是 None,则与异常的行进行比较。如果 offset 不是 None,则与异常的偏移量进行比较。

test.support.open_urlresource(url, *args, **kw)

打开 url。如果打开失败,则引发 TestFailed

test.support.reap_children()

每当启动子进程时,在 test_main 的末尾使用此方法。这将有助于确保没有额外的子进程(僵尸)滞留,占用资源并在查找内存泄漏时造成问题。

test.support.get_attribute(obj, name)

获取属性,如果引发 AttributeError,则引发 unittest.SkipTest

test.support.catch_unraisable_exception()

使用 sys.unraisablehook() 捕获无法引发的异常的上下文管理器。

存储异常值(cm.unraisable.exc_value)会创建引用循环。当上下文管理器退出时,引用循环会被显式打破。

如果将对象设置为正在最终化的对象,则存储对象(cm.unraisable.object)可以使其复活。退出上下文管理器会清除存储的对象。

用法

with support.catch_unraisable_exception() as cm:
    # code creating an "unraisable exception"
    ...

    # check the unraisable exception: use cm.unraisable
    ...

# cm.unraisable attribute no longer exists at this point
# (to break a reference cycle)

在版本 3.8 中添加。

test.support.load_package_tests(pkg_dir, loader, standard_tests, pattern)

用于测试包的 unittest load_tests 协议的通用实现。pkg_dir 是包的根目录;loaderstandard_testspatternload_tests 期望的参数。在简单的情况下,测试包的 __init__.py 可以是以下内容

import os
from test.support import load_package_tests

def load_tests(*args):
    return load_package_tests(os.path.dirname(__file__), *args)
test.support.detect_api_mismatch(ref_api, other_api, *, ignore=())

返回 other_api 上未找到的 ref_api 的属性、函数或方法的集合,除了 ignore 中指定的要在此检查中忽略的已定义项目列表。

默认情况下,这会跳过以“_”开头的私有属性,但包括所有魔术方法,即以“__”开头和结尾的方法。

在版本 3.5 中添加。

test.support.patch(test_instance, object_to_patch, attr_name, new_value)

使用 new_value 覆盖 object_to_patch.attr_name。还向 test_instance 添加清理过程,以还原 object_to_patchattr_nameattr_name 应该是 object_to_patch 的有效属性。

test.support.run_in_subinterp(code)

在子解释器中运行 code。如果启用了 tracemalloc,则引发 unittest.SkipTest

test.support.check_free_after_iterating(test, iter, cls, args=())

断言在迭代后释放 cls 的实例。

test.support.missing_compiler_executable(cmd_names=[])

检查 cmd_names 中列出的编译器可执行文件是否存在,或者在 cmd_names 为空时检查所有编译器可执行文件是否存在,并返回第一个缺失的可执行文件,或者在未找到缺失的可执行文件时返回 None

test.support.check__all__(test_case, module, name_of_module=None, extra=(), not_exported=())

断言 模块__all__ 变量包含所有公共名称。

模块的公共名称(其 API)是根据它们是否符合公共名称约定以及是否在 模块 中定义来自动检测的。

name_of_module 参数可以指定(作为字符串或字符串元组)在哪些模块中可以定义 API,以便被检测为公共 API。一种情况是当 模块 从其他模块导入其部分公共 API 时,可能是 C 后端(如 csv 及其 _csv)。

extra 参数可以是一组名称,这些名称通常不会被自动检测为“公共”,例如没有适当 __module__ 属性的对象。如果提供,它将被添加到自动检测的名称中。

not_exported 参数可以是一组名称,即使它们的名称另有指示,也不得将其视为公共 API 的一部分。

用法示例

import bar
import foo
import unittest
from test import support

class MiscTestCase(unittest.TestCase):
    def test__all__(self):
        support.check__all__(self, foo)

class OtherTestCase(unittest.TestCase):
    def test__all__(self):
        extra = {'BAR_CONST', 'FOO_CONST'}
        not_exported = {'baz'}  # Undocumented name.
        # bar imports part of its API from _bar.
        support.check__all__(self, bar, ('bar', '_bar'),
                             extra=extra, not_exported=not_exported)

在 3.6 版本中新增。

test.support.skip_if_broken_multiprocessing_synchronize()

如果缺少 multiprocessing.synchronize 模块,如果没有可用的信号量实现,或者创建锁引发 OSError,则跳过测试。

在 3.10 版本中新增。

test.support.check_disallow_instantiation(test_case, tp, *args, **kwds)

断言不能使用 argskwds 实例化类型 tp

在 3.10 版本中新增。

test.support.adjust_int_max_str_digits(max_digits)

此函数返回一个上下文管理器,该管理器将在上下文持续时间内更改全局 sys.set_int_max_str_digits() 设置,以允许执行需要在整数和字符串之间转换时对位数进行不同限制的测试代码。

3.11 版本中新增。

test.support 模块定义了以下类

class test.support.SuppressCrashReport

一个上下文管理器,用于尝试阻止在预期会使子进程崩溃的测试中弹出崩溃对话框。

在 Windows 上,它使用 SetErrorMode 禁用 Windows 错误报告对话框。

在 UNIX 上,使用 resource.setrlimit()resource.RLIMIT_CORE 的软限制设置为 0,以防止创建核心转储文件。

在两个平台上,旧值都由 __exit__() 恢复。

class test.support.SaveSignals

用于保存和恢复 Python 信号处理程序注册的信号处理程序的类。

save(self)

将信号处理程序保存到将信号编号映射到当前信号处理程序的字典中。

restore(self)

save() 字典中的信号编号设置为保存的处理程序。

class test.support.Matcher
matches(self, d, **kwargs)

尝试将单个字典与提供的参数匹配。

match_value(self, k, dv, v)

尝试将单个存储的值 (dv) 与提供的值 (v) 匹配。

test.support.socket_helper — 套接字测试的实用工具

test.support.socket_helper 模块为套接字测试提供支持。

3.9 版本中新增。

test.support.socket_helper.IPV6_ENABLED

如果在此主机上启用 IPv6,则设置为 True,否则设置为 False

test.support.socket_helper.find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM)

返回一个适合绑定的未使用的端口。这是通过创建一个具有与 sock 参数相同的族和类型的临时套接字(默认为 AF_INETSOCK_STREAM),并将其绑定到指定的主机地址(默认为 0.0.0.0),端口设置为 0,从而从操作系统获取未使用的临时端口来实现的。然后关闭并删除临时套接字,并返回临时端口。

对于任何需要在测试期间将服务器套接字绑定到特定端口的测试,应使用此方法或 bind_port()。使用哪一个取决于调用代码是创建 Python 套接字,还是需要在构造函数中提供未使用的端口或传递给外部程序(即 openssl 的 s_server 模式的 -accept 参数)。尽可能优先使用 bind_port() 而不是 find_unused_port()。不鼓励使用硬编码端口,因为它会使测试的多个实例无法同时运行,这对构建机器人来说是一个问题。

test.support.socket_helper.bind_port(sock, host=HOST)

将套接字绑定到一个空闲端口并返回端口号。依赖于临时端口以确保我们使用的是未绑定的端口。这很重要,因为许多测试可能会同时运行,尤其是在构建机器人环境中。如果 sock.familyAF_INETsock.typeSOCK_STREAM,并且套接字上设置了 SO_REUSEADDRSO_REUSEPORT,此方法会引发异常。测试绝不应为 TCP/IP 套接字设置这些套接字选项。设置这些选项的唯一情况是通过多个 UDP 套接字测试多播。

此外,如果 SO_EXCLUSIVEADDRUSE 套接字选项可用(即在 Windows 上),它将被设置在套接字上。这将阻止其他人在测试期间绑定到我们的主机/端口。

test.support.socket_helper.bind_unix_socket(sock, addr)

绑定 Unix 套接字,如果引发 PermissionError,则引发 unittest.SkipTest

@test.support.socket_helper.skip_unless_bind_unix_socket

一个装饰器,用于运行需要 Unix 套接字 bind() 功能的测试。

test.support.socket_helper.transient_internet(resource_name, *, timeout=30.0, errnos=())

一个上下文管理器,当互联网连接的各种问题表现为异常时,会引发 ResourceDenied

test.support.script_helper — Python 执行测试的实用工具

test.support.script_helper 模块为 Python 的脚本执行测试提供支持。

test.support.script_helper.interpreter_requires_environment()

如果 sys.executable interpreter 需要环境变量才能完全运行,则返回 True

此函数旨在与 @unittest.skipIf() 一起使用,以注释需要使用 assert_python*() 函数来启动隔离模式 (-I) 或无环境模式 (-E) 子解释器进程的测试。

正常的构建和测试不会遇到这种情况,但在尝试从没有 Python 当前查找逻辑的明显主目录的解释器运行标准库测试套件时可能会发生这种情况。

设置 PYTHONHOME 是使大多数测试套件在这种情况下运行的一种方法。 PYTHONPATHPYTHONUSERSITE 是其他可能影响解释器是否可以启动的常见环境变量。

test.support.script_helper.run_python_until_end(*args, **env_vars)

根据 *env_vars* 设置环境,以便在子进程中运行解释器。这些值可以包括 __isolated__cleanenv__cwdTERM

在 3.9 版本中更改: 该函数不再从 *stderr* 中去除空格。

test.support.script_helper.assert_python_ok(*args, **env_vars)

断言使用 *args* 和可选环境变量 *env_vars* 运行解释器成功 (rc == 0) 并返回一个 (return code, stdout, stderr) 元组。

如果设置了仅限关键字的参数 *__cleanenv*,则 *env_vars* 将用作新的环境。

Python 在隔离模式下启动(命令行选项 -I),除非将仅限关键字的参数 *__isolated* 设置为 False

在 3.9 版本中更改: 该函数不再从 *stderr* 中去除空格。

test.support.script_helper.assert_python_failure(*args, **env_vars)

断言使用 *args* 和可选环境变量 *env_vars* 运行解释器失败 (rc != 0) 并返回一个 (return code, stdout, stderr) 元组。

有关更多选项,请参见 assert_python_ok()

在 3.9 版本中更改: 该函数不再从 *stderr* 中去除空格。

test.support.script_helper.spawn_python(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw)

使用给定的参数运行 Python 子进程。

kw 是传递给 subprocess.Popen() 的额外关键字参数。返回一个 subprocess.Popen 对象。

test.support.script_helper.kill_python(p)

运行给定的 subprocess.Popen 进程直到完成,并返回 stdout。

test.support.script_helper.make_script(script_dir, script_basename, source, omit_suffix=False)

在路径 *script_dir* 和 *script_basename* 中创建包含 *source* 的脚本。如果 *omit_suffix* 是 False,则将 .py 附加到名称。返回完整的脚本路径。

test.support.script_helper.make_zip_script(zip_dir, zip_basename, script_name, name_in_zip=None)

zip_dirzip_basename 创建一个扩展名为 zip 的 zip 文件,其中包含 script_name 中的文件。name_in_zip 是压缩包中的名称。返回一个包含 (完整路径, 压缩包中名称的完整路径) 的元组。

test.support.script_helper.make_pkg(pkg_dir, init_source='')

创建一个名为 pkg_dir 的目录,其中包含一个 __init__ 文件,其内容为 init_source

test.support.script_helper.make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, source, depth=1, compiled=False)

创建一个 zip 包目录,其路径为 zip_dirzip_basename,其中包含一个空的 __init__ 文件和一个包含 sourcescript_basename 文件。如果 compiledTrue,则会将源文件编译并添加到 zip 包中。返回一个包含完整 zip 路径和 zip 文件压缩包名称的元组。

test.support.bytecode_helper — 用于测试正确字节码生成的支持工具

test.support.bytecode_helper 模块提供了用于测试和检查字节码生成的支持。

3.9 版本中新增。

该模块定义了以下类

class test.support.bytecode_helper.BytecodeTestCase(unittest.TestCase)

此类具有用于检查字节码的自定义断言方法。

BytecodeTestCase.get_disassembly_as_string(co)

返回 co 的反汇编字符串。

BytecodeTestCase.assertInBytecode(x, opname, argval=_UNSPECIFIED)

如果找到 opname,则返回指令,否则抛出 AssertionError

BytecodeTestCase.assertNotInBytecode(x, opname, argval=_UNSPECIFIED)

如果找到 opname,则抛出 AssertionError

test.support.threading_helper — 用于线程测试的实用工具

test.support.threading_helper 模块提供了对线程测试的支持。

在 3.10 版本中新增。

test.support.threading_helper.join_thread(thread, timeout=None)

timeout 时间内等待 thread 线程结束。如果线程在 timeout 秒后仍然存活,则抛出 AssertionError

@test.support.threading_helper.reap_threads

装饰器,用于确保即使测试失败,线程也会被清理。

test.support.threading_helper.start_threads(threads, unlock=None)

上下文管理器,用于启动 threads(一个线程序列)。unlock 是一个函数,在线程启动后被调用,即使引发了异常也会被调用;一个例子是 threading.Event.set()start_threads 将尝试在退出时等待已启动的线程结束。

test.support.threading_helper.threading_cleanup(*original_values)

清理 original_values 中未指定的线程。旨在如果测试在后台留下正在运行的线程,则发出警告。

test.support.threading_helper.threading_setup()

返回当前线程计数和悬挂线程的副本。

test.support.threading_helper.wait_threads_exit(timeout=None)

上下文管理器,用于等待 with 语句中创建的所有线程退出。

test.support.threading_helper.catch_threading_exception()

上下文管理器,使用 threading.excepthook() 捕获 threading.Thread 异常。

捕获到异常时设置的属性

  • exc_type

  • exc_value

  • exc_traceback

  • thread

请参阅 threading.excepthook() 文档。

这些属性在上下文管理器退出时被删除。

用法

with threading_helper.catch_threading_exception() as cm:
    # code spawning a thread which raises an exception
    ...

    # check the thread exception, use cm attributes:
    # exc_type, exc_value, exc_traceback, thread
    ...

# exc_type, exc_value, exc_traceback, thread attributes of cm no longer
# exists at this point
# (to avoid reference cycles)

在版本 3.8 中添加。

test.support.os_helper — 用于操作系统测试的实用工具

test.support.os_helper 模块为 os 测试提供支持。

在 3.10 版本中新增。

test.support.os_helper.FS_NONASCII

一个可以通过 os.fsencode() 编码的非 ASCII 字符。

test.support.os_helper.SAVEDCWD

设置为 os.getcwd()

test.support.os_helper.TESTFN

设置为一个可以安全用作临时文件名称的名称。任何创建的临时文件都应该被关闭和取消链接(移除)。

test.support.os_helper.TESTFN_NONASCII

设置为一个包含 FS_NONASCII 字符的文件名(如果存在)。这保证了如果文件名存在,则可以使用默认的文件系统编码进行编码和解码。这允许在无法工作的平台上轻松跳过需要非 ASCII 文件名的测试。

test.support.os_helper.TESTFN_UNENCODABLE

设置为一个文件名(str 类型),该文件名不应能够以严格模式通过文件系统编码进行编码。如果无法生成此类文件名,则可能为 None

test.support.os_helper.TESTFN_UNDECODABLE

设置为一个文件名(bytes 类型),该文件名不应能够以严格模式通过文件系统编码进行解码。如果无法生成此类文件名,则可能为 None

test.support.os_helper.TESTFN_UNICODE

设置为临时文件的非 ASCII 名称。

class test.support.os_helper.EnvironmentVarGuard

用于临时设置或取消设置环境变量的类。实例可以用作上下文管理器,并且具有完整的字典接口,用于查询/修改底层的 os.environ。退出上下文管理器后,所有通过此实例对环境变量所做的更改都将被回滚。

在 3.1 版本中更改: 添加了字典接口。

class test.support.os_helper.FakePath(path)

简单的 路径类对象。它实现了 __fspath__() 方法,该方法仅返回 path 参数。如果 path 是一个异常,它将在 __fspath__() 中引发。

EnvironmentVarGuard.set(envvar, value)

临时将环境变量 envvar 设置为 value 的值。

EnvironmentVarGuard.unset(envvar)

临时取消设置环境变量 envvar

如果操作系统支持符号链接,则返回 True,否则返回 False

test.support.os_helper.can_xattr()

如果操作系统支持 xattr,则返回 True,否则返回 False

test.support.os_helper.change_cwd(path, quiet=False)

一个上下文管理器,将当前工作目录临时更改为 path 并返回目录。

如果 quietFalse,则上下文管理器会在出错时引发异常。否则,它仅发出警告并保持当前工作目录不变。

test.support.os_helper.create_empty_file(filename)

创建一个名为 filename 的空文件。如果它已经存在,则将其截断。

test.support.os_helper.fd_count()

计算打开的文件描述符的数量。

test.support.os_helper.fs_is_case_insensitive(directory)

如果 directory 的文件系统不区分大小写,则返回 True

test.support.os_helper.make_bad_fd()

通过打开和关闭临时文件并返回其描述符来创建无效的文件描述符。

test.support.os_helper.rmdir(filename)

filename 上调用 os.rmdir()。在 Windows 平台上,这会包装一个等待循环,该循环会检查文件是否存在,这是由于防病毒程序可能会保持文件打开并阻止删除。

test.support.os_helper.rmtree(path)

path 上调用 shutil.rmtree() 或调用 os.lstat()os.rmdir() 来删除路径及其内容。与 rmdir() 一样,在 Windows 平台上,这会包装一个等待循环,该循环会检查文件是否存在。

一个用于运行需要符号链接支持的测试的装饰器。

@test.support.os_helper.skip_unless_xattr

一个用于运行需要 xattr 支持的测试的装饰器。

test.support.os_helper.temp_cwd(name='tempcwd', quiet=False)

一个上下文管理器,它临时创建一个新目录并更改当前工作目录 (CWD)。

此上下文管理器在临时更改当前工作目录之前,在当前目录中创建一个名为 name 的临时目录。如果 nameNone,则使用 tempfile.mkdtemp() 创建临时目录。

如果 quietFalse 且无法创建或更改 CWD,则会引发错误。否则,只会引发警告并使用原始 CWD。

test.support.os_helper.temp_dir(path=None, quiet=False)

一个上下文管理器,它在 path 处创建一个临时目录并生成该目录。

如果 pathNone,则使用 tempfile.mkdtemp() 创建临时目录。如果 quietFalse,则上下文管理器会在出错时引发异常。否则,如果指定了 path 且无法创建,则只会发出警告。

test.support.os_helper.temp_umask(umask)

一个上下文管理器,它临时设置进程 umask。

filename 上调用 os.unlink()。与 rmdir() 一样,在 Windows 平台上,它被包装在一个等待循环中,该循环检查文件是否存在。

test.support.import_helper — 用于导入测试的实用程序

test.support.import_helper 模块为导入测试提供支持。

在 3.10 版本中新增。

test.support.import_helper.forget(module_name)

sys.modules 中删除名为 module_name 的模块,并删除该模块的任何字节编译文件。

test.support.import_helper.import_fresh_module(name, fresh=(), blocked=(), deprecated=False)

此函数通过在执行导入之前从 sys.modules 中删除指定的模块,来导入并返回指定 Python 模块的全新副本。 请注意,与 reload() 不同,原始模块不受此操作的影响。

fresh 是一个额外的模块名称的可迭代对象,在执行导入之前也会从 sys.modules 缓存中删除。

blocked 是模块名称的可迭代对象,在导入期间,这些模块名称在模块缓存中被替换为 None,以确保尝试导入它们会引发 ImportError

在开始导入之前,会保存指定模块和 freshblocked 参数中指定的任何模块,然后在全新导入完成后,将其重新插入到 sys.modules 中。

如果 deprecatedTrue,则在此导入期间会抑制模块和包的弃用消息。

如果无法导入指定的模块,则此函数将引发 ImportError

用法示例

# Get copies of the warnings module for testing without affecting the
# version being used by the rest of the test suite. One copy uses the
# C implementation, the other is forced to use the pure Python fallback
# implementation
py_warnings = import_fresh_module('warnings', blocked=['_warnings'])
c_warnings = import_fresh_module('warnings', fresh=['_warnings'])

在版本 3.1 中添加。

test.support.import_helper.import_module(name, deprecated=False, *, required_on=())

此函数会导入并返回指定的模块。 与正常的导入不同,如果无法导入模块,此函数会引发 unittest.SkipTest

如果 deprecatedTrue,则在此导入期间会抑制模块和包的弃用消息。 如果模块在某个平台上是必需的,但在其他平台上是可选的,请将 required_on 设置为平台前缀的可迭代对象,这些前缀将与 sys.platform 进行比较。

在版本 3.1 中添加。

test.support.import_helper.modules_setup()

返回 sys.modules 的副本。

test.support.import_helper.modules_cleanup(oldmodules)

删除除 oldmodulesencodings 之外的模块,以保留内部缓存。

test.support.import_helper.unload(name)

sys.modules 中删除 name

test.support.import_helper.make_legacy_pyc(source)

PEP 3147/PEP 488 pyc 文件移动到其旧的 pyc 位置,并返回旧的 pyc 文件的文件系统路径。 source 值是源文件的文件系统路径。 它不需要存在,但是 PEP 3147/488 pyc 文件必须存在。

class test.support.import_helper.CleanImport(*module_names)

一个上下文管理器,用于强制导入返回新的模块引用。 这对于测试模块级行为非常有用,例如在导入时发出 DeprecationWarning。 用法示例

with CleanImport('foo'):
    importlib.import_module('foo')  # New reference.
class test.support.import_helper.DirsOnSysPath(*paths)

一个上下文管理器,用于临时将目录添加到 sys.path

这将复制 sys.path,追加任何作为位置参数给定的目录,然后在上下文结束时将 sys.path 恢复为复制的设置。

请注意,上下文管理器主体中所有sys.path 的修改,包括对象的替换,都将在代码块结束时恢复。

test.support.warnings_helper — 警告测试的实用工具

test.support.warnings_helper 模块为警告测试提供支持。

在 3.10 版本中新增。

test.support.warnings_helper.ignore_warnings(*, category)

抑制属于 category 实例的警告,category 必须是 Warning 或其子类。大致等同于调用 warnings.catch_warnings() 并设置 warnings.simplefilter('ignore', category=category)。例如:

@warning_helper.ignore_warnings(category=DeprecationWarning)
def test_suppress_warning():
    # do something

在版本 3.8 中添加。

test.support.warnings_helper.check_no_resource_warning(testcase)

检查没有引发 ResourceWarning 的上下文管理器。您必须在上下文管理器结束之前删除可能发出 ResourceWarning 的对象。

test.support.warnings_helper.check_syntax_warning(testcase, statement, errtext='', *, lineno=1, offset=None)

通过尝试编译 statement 来测试 statement 中的语法警告。同时测试 SyntaxWarning 是否只发出一次,以及在转化为错误时是否会被转换为 SyntaxErrortestcase 是测试的 unittest 实例。errtext 是应该匹配发出的 SyntaxWarning 和引发的 SyntaxError 的字符串表示形式的正则表达式。如果 lineno 不是 None,则与警告和异常的行进行比较。如果 offset 不是 None,则与异常的偏移量进行比较。

在版本 3.8 中添加。

test.support.warnings_helper.check_warnings(*filters, quiet=True)

一个方便的 warnings.catch_warnings() 包装器,可以更轻松地测试是否正确引发了警告。它大致等同于调用 warnings.catch_warnings(record=True) 并将 warnings.simplefilter() 设置为 always,并可以选择自动验证记录的结果。

check_warnings 接受形如 ("message regexp", WarningCategory) 的 2 元组作为位置参数。如果提供了一个或多个 filters,或者可选关键字参数 quietFalse,它会检查以确保警告符合预期:每个指定的过滤器必须至少匹配封闭代码引发的一个警告,否则测试将失败;如果引发了任何不匹配任何指定过滤器的警告,则测试将失败。要禁用第一个检查,请将 quiet 设置为 True

如果没有指定参数,则默认为

check_warnings(("", Warning), quiet=True)

在这种情况下,所有警告都会被捕获,且不会引发错误。

在进入上下文管理器时,会返回一个 WarningRecorder 实例。可以通过记录器对象的 warnings 属性访问来自 catch_warnings() 的底层警告列表。为了方便起见,也可以通过记录器对象直接访问表示最近警告的对象的属性(请参见下面的示例)。如果没有引发警告,则任何在表示警告的对象上可能存在的属性都将返回 None

记录器对象还有一个 reset() 方法,该方法会清除警告列表。

上下文管理器设计为这样使用

with check_warnings(("assertion is always true", SyntaxWarning),
                    ("", UserWarning)):
    exec('assert(False, "Hey!")')
    warnings.warn(UserWarning("Hide me!"))

在这种情况下,如果未引发任一警告,或者引发了其他一些警告,check_warnings() 将会引发错误。

当测试需要更深入地查看警告时,而不仅仅是检查是否发生警告时,可以使用如下代码

with check_warnings(quiet=True) as w:
    warnings.warn("foo")
    assert str(w.args[0]) == "foo"
    warnings.warn("bar")
    assert str(w.args[0]) == "bar"
    assert str(w.warnings[0].args[0]) == "foo"
    assert str(w.warnings[1].args[0]) == "bar"
    w.reset()
    assert len(w.warnings) == 0

这里会捕获所有警告,并且测试代码会直接测试捕获的警告。

在 3.2 版本中更改: 新增可选参数 filtersquiet

class test.support.warnings_helper.WarningsRecorder

用于记录单元测试警告的类。有关更多详细信息,请参见上面 check_warnings() 的文档。