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 撰写的一本关于在编写代码之前编写测试的书。

使用命令行界面运行测试

test 包可以作为脚本运行以驱动 Python 的回归测试套件,这要归功于 -m 选项:python -m test。它在底层使用了 test.regrtest;在之前的 Python 版本中使用的调用 python -m test.regrtest 仍然有效。单独运行脚本会自动开始运行 test 包中的所有回归测试。它通过查找包中名称以 test_ 开头的所有模块,导入它们,并在存在 test_main() 函数时执行它,或者如果 test_main 不存在,则通过 unittest.TestLoader.loadTestsFromModule 加载测试来实现这一点。要执行的测试的名称也可以传递给脚本。指定单个回归测试 (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。当需要有关正在运行的测试的更多详细信息时,应检查此项。 *verbose* 由 test.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_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

如果使用定义的 Py_DEBUG 宏构建 Python(即,如果 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。如果引发 ResourceDenied,则 msg 是其参数。如果由 __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 开始时的 stdout。

test.support.get_original_stdout()

返回由 record_original_stdout() 设置的原始 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):
    ...

这会将 obj.attrwith 代码块的持续时间内设置为 5,并在代码块结束时恢复旧值。如果 obj 上不存在 attr,则将在代码块结束时创建并删除它。

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

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

上下文管理器,用于将项目替换为新对象。

用法

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

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

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

test.support.flush_std_streams()

sys.stdout 上调用 flush() 方法,然后在 sys.stderr 上调用。它可以用来确保在写入 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)

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

test.support.calcvobjsize(fmt)

返回结构成员由 fmt 定义的 PyVarObject 的大小。返回值包括 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_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 添加清理过程,以便为 attr_name 恢复 object_to_patchattr_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=())

断言 *module* 的 __all__ 变量包含所有公共名称。

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

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

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

断言类型 *tp* 不能使用 *args* 和 *kwds* 实例化。

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 解释器 需要环境变量才能运行,则返回 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 进程直至完成,并返回标准输出。

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

在路径 script_dirscript_basename 中创建包含 source 的脚本。如果 omit_suffixFalse,则将 .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_dirzip_basename 的 zip 包目录,其中包含一个空的 __init__ 文件和一个包含 source 的文件 script_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 模块为操作系统测试提供支持。

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

设置为在严格模式下无法由文件系统编码解码的文件名(字节类型)。如果无法生成这样的文件名,则它可能是 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 实例的警告,它必须是 Warning 或其子类。大致相当于使用 warnings.simplefilter('ignore', category=category)warnings.catch_warnings()。例如

@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 来测试其中的语法警告。还要测试 SyntaxWarning 是否只发出一次,以及在转换为错误时是否会转换为 SyntaxErrortestcase 是用于测试的 unittest 实例。errtext 是应该与发出的 SyntaxWarning 和引发的 SyntaxError 的字符串表示形式匹配的正则表达式。如果 lineno 不是 None,则与警告和异常的行进行比较。如果 offset 不是 None,则与异常的偏移量进行比较。

3.8 版新增。

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

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

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() 文档。