运行测试¶
这是我们的测试框架。
目标:
它应与 py.test 兼容,并且操作非常相似(或相同)
不需要任何外部依赖
最好所有功能都只在这个文件中实现
没有魔法,只需导入测试文件并执行测试函数,就是这样。
便携式
- class sympy.testing.runtests.PyTestReporter(
- verbose=False,
- tb='short',
- colors=True,
- force_colors=False,
- split=None,
Py.test 类似的报告器。应生成与 py.test 相同的输出。
- 属性:
- terminal_width
方法
write
(text[, color, align, width, force_colors])在屏幕上打印文本。
doctest_fail
输入文件名
进入测试
完成
导入错误
leaving_filename
root_dir
开始
测试异常
测试失败
测试通过
test_skip
test_xfail
test_xpass
write_center
write_exception
- class sympy.testing.runtests.SymPyDocTestFinder(
- verbose=False,
- parser=<doctest.DocTestParser object>,
- recurse=True,
- exclude_empty=True,
一个用于从给定对象的文档字符串及其包含对象的文档字符串中提取相关DocTests的类。目前可以从以下对象类型中提取DocTests:模块、函数、类、方法、静态方法、类方法和属性。
从 doctest 的版本修改而来,以更难发现代码来自不同的模块。例如,@vectorize 装饰器使得函数看起来像是来自 multidimensional.py,尽管它们的代码存在于其他地方。
方法
find
(obj[, name, module, globs, extraglobs])返回由给定对象的文档字符串定义的DocTests列表,或由其包含的任何对象的文档字符串定义的DocTests列表。
- class sympy.testing.runtests.SymPyDocTestRunner(
- checker=None,
- verbose=None,
- optionflags=0,
一个用于运行 DocTest 测试用例并累积统计数据的类。
run
方法用于处理单个 DocTest 用例。它返回一个元组(f, t)
,其中t
是尝试的测试用例数量,f
是失败的测试用例数量。从doctest版本修改以不重置sys.displayhook(参见问题5140)。
更多信息请参阅原始 DocTestRunner 的文档字符串。
方法
merge
(other)report_failure
(out, test, example, got)报告给定的示例失败。
report_start
(out, test, example)报告测试运行器即将处理给定的示例。
report_success
(out, test, example, got)报告给定的示例已成功运行。
report_unexpected_exception
(out, test, ...)报告给定的示例引发了意外的异常。
run
(test[, compileflags, out, clear_globs])在
test
中运行示例,并使用out
函数显示结果。summarize
([verbose])打印由该 DocTestRunner 运行的所有测试用例的摘要,并返回一个元组 \((f, t)\),其中 \(f\) 是失败示例的总数,\(t\) 是尝试示例的总数。
- run(
- test,
- compileflags=None,
- out=None,
- clear_globs=True,
在
test
中运行示例,并使用out
函数显示结果。示例在命名空间
test.globs
中运行。如果clear_globs
为真(默认),则在测试运行后将清除该命名空间,以帮助垃圾回收。如果你希望在测试完成后检查命名空间,则使用clear_globs=False
。compileflags
给出了在运行示例时Python编译器应使用的标志集。如果未指定,则它将默认为适用于globs
的未来导入标志集。每个示例的输出都使用
SymPyDocTestRunner.check_output
进行检查,结果由SymPyDocTestRunner.report_*
方法格式化。
- class sympy.testing.runtests.SymPyOutputChecker[源代码][源代码]¶
与标准库中的 OutputChecker 相比,我们的 OutputChecker 类支持 doctest 示例输出中浮点数的数值比较。
方法
check_output
(want, got, optionflags)当示例的实际输出 (\(got\)) 与预期输出 (\(want\)) 匹配时返回 True。
output_difference
(example, got, optionflags)返回一个字符串,描述给定示例 (\(example\)) 的预期输出与实际输出 (\(got\)) 之间的差异。
- class sympy.testing.runtests.SymPyTestResults(failed, attempted)[源代码]¶
方法
count
(value, /)返回值出现的次数。
index
(value[, start, stop])返回值的第一个索引。
- attempted¶
字段编号1的别名
- failed¶
字段编号 0 的别名
- sympy.testing.runtests.convert_to_native_paths(lst)[源代码][源代码]¶
将一个由 ‘/’ 分隔的路径列表转换为本地(os.sep 分隔)路径列表,如果系统不区分大小写,则转换为小写。
- sympy.testing.runtests.doctest(
- *paths,
- subprocess=True,
- rerun=0,
- **kwargs,
在SymPy目录中运行所有匹配``paths``中给定字符串的*.py文件中的doctests,如果paths=[],则运行所有测试。
注释:
路径可以以原生系统格式或unix的前斜杠格式输入。
黑名单中的文件可以通过提供其路径进行测试;只有在没有给出路径时,它们才会被排除。
示例
>>> import sympy
运行所有测试:
>>> sympy.doctest()
运行一个文件:
>>> sympy.doctest("sympy/core/basic.py") >>> sympy.doctest("polynomial.rst")
运行 sympy/functions/ 中的所有测试以及一些特定文件:
>>> sympy.doctest("/functions", "basic.py")
运行任何名称中包含 polynomial 的文件,如 doc/src/modules/polynomial.rst、sympy/functions/special/polynomials.py 和 sympy/polys/polynomial.py:
>>> sympy.doctest("polynomial")
split
选项可以传递给将测试运行分成多个部分。当前的分割仅限于测试文件,尽管这在未来可能会改变。split
应该是一个形式为 ‘a/b’ 的字符串,它将运行b
部分的第a
部分。请注意,常规的 doctests 和 Sphinx doctests 是独立分割的。例如,要运行测试套件的前半部分:>>> sympy.doctest(split='1/2')
subprocess
和verbose
选项与函数test()
的选项相同(更多信息请参阅该函数的文档字符串),除了verbose
也可以设置为2
,以便在测试时打印单个 doctest 行。
- sympy.testing.runtests.raise_on_deprecated()[源代码][源代码]¶
上下文管理器使 DeprecationWarning 引发错误
这是为了在运行测试和文档测试时捕获库代码中的 SymPyDeprecationWarning。在每个单独的测试/文档测试周围使用此上下文管理器非常重要,以防某些测试修改警告过滤器。
- sympy.testing.runtests.run_all_tests(
- test_args=(),
- test_kwargs=None,
- doctest_args=(),
- doctest_kwargs=None,
- examples_args=(),
- examples_kwargs=None,
运行所有测试。
目前,这会运行常规测试(bin/test)、文档测试(bin/doctest)和示例(examples/all.py)。
这就是
setup.py test
所使用的。你可以将参数和关键字参数传递给支持它们的测试函数(目前是 test、doctest 和 examples)。有关可用选项的描述,请参阅这些函数的文档字符串。
例如,要关闭颜色运行求解器测试:
>>> from sympy.testing.runtests import run_all_tests >>> run_all_tests(test_args=("solvers",), ... test_kwargs={"colors:False"})
- sympy.testing.runtests.run_in_subprocess_with_hash_randomization(
- function,
- function_args=(),
- function_kwargs=None,
- command='/Users/cw/baidu/code/fin_tool/github/sympy/venv/bin/python',
- module='sympy.testing.runtests',
- force=False,
在启用哈希随机化的Python子进程中运行一个函数。
如果给定的 Python 版本不支持哈希随机化,则返回 False。否则,它返回命令的退出值。该函数传递给 sys.exit(),因此函数的返回值将是返回值。
环境变量 PYTHONHASHSEED 用于种子化 Python 的哈希随机化。如果设置了该变量,此函数将返回 False,因为在这种情况下启动新的子进程是不必要的。如果未设置,则会随机设置一个值,并运行测试。请注意,如果在 Python 启动时设置了此环境变量,哈希随机化将自动启用。要强制创建子进程,即使设置了 PYTHONHASHSEED,也可以传递
force=True
。此标志不会在 Python 版本中强制创建子进程,这些版本不支持哈希随机化(见下文),因为这些版本的 Python 不支持-R
标志。function
应该是一个可以从module
模块导入的函数名称,例如 “_test”。module
的默认值是 “sympy.testing.runtests”。function_args
和function_kwargs
应该分别是可 repr 的元组和字典。默认的 Python 命令是 sys.executable,即当前运行的 Python 命令。这个函数是必要的,因为哈希随机化的种子必须在Python启动之前由环境变量设置。因此,为了在测试中使用预定的种子,我们必须在一个单独的子进程中启动Python。
哈希随机化在 Python 次版本 2.6.8、2.7.3、3.1.5 和 3.2.3 中被添加,并且在所有 Python 3.3.0 及之后的版本中默认启用。
示例
>>> from sympy.testing.runtests import ( ... run_in_subprocess_with_hash_randomization) >>> # run the core tests in verbose mode >>> run_in_subprocess_with_hash_randomization("_test", ... function_args=("core",), ... function_kwargs={'verbose': True}) # Will return 0 if sys.executable supports hash randomization and tests # pass, 1 if they fail, and False if it does not support hash # randomization.
- sympy.testing.runtests.split_list(l, split, density=None)[源代码][源代码]¶
将一个列表分成 b 份中的 a 份
split 应该是一个形如 ‘a/b’ 的字符串。例如,’1/3’ 将给出三分之一的分割。
如果列表的长度不能被分割的数量整除,最后一个分割将包含更多的项目。
\(density\) 可以指定为一个列表。如果指定,测试将被平衡,以便每个分割根据 \(density\) 具有尽可能相等的质量。
>>> from sympy.testing.runtests import split_list >>> a = list(range(10)) >>> split_list(a, '1/3') [0, 1, 2] >>> split_list(a, '2/3') [3, 4, 5] >>> split_list(a, '3/3') [6, 7, 8, 9]
- sympy.testing.runtests.sympytestfile(
- filename,
- module_relative=True,
- name=None,
- package=None,
- globs=None,
- verbose=None,
- report=True,
- optionflags=0,
- extraglobs=None,
- raise_on_error=False,
- parser=<doctest.DocTestParser object>,
- encoding=None,
在给定文件中测试示例。返回 (#失败数, #测试数)。
可选的关键字参数
module_relative
指定文件名应如何解释:如果
module_relative
为 True(默认值),那么filename
指定一个模块相关的路径。默认情况下,此路径相对于调用模块的目录;但如果指定了package
参数,则路径相对于该包。为了确保操作系统的独立性,filename
应使用 “/” 字符来分隔路径段,并且不应是绝对路径(即,它不能以 “/” 开头)。如果
module_relative
为 False,那么filename
指定一个特定于操作系统的路径。该路径可以是绝对路径,也可以是相对路径(相对于当前工作目录)。
可选的关键字参数
name
给出了测试的名称;默认使用文件的基本名称。可选的关键字参数
package
是一个 Python 包或 Python 包的名称,其目录应作为模块相对文件名的基础目录。如果没有指定包,则使用调用模块的目录作为模块相对文件名的基础目录。如果module_relative
为 False,则指定package
是错误的。可选的关键字参数
globs
提供了一个字典,在执行示例时用作全局变量;默认使用 {}。这个字典的副本实际上用于每个文档字符串,以便每个文档字符串的示例从一个干净的起点开始。可选的关键字参数
extraglobs
提供了一个字典,该字典应合并到用于执行示例的全局变量中。默认情况下,不使用额外的全局变量。可选的关键字参数
verbose
如果为真,则打印大量内容;如果为假,则仅打印失败信息;默认情况下,如果 sys.argv 中包含 “-v”,则为真。可选的关键字参数
report
在为真时在末尾打印一个总结,否则不打印任何内容。在详细模式下,总结是详细的,否则非常简短(实际上,如果所有测试都通过,则为空)。可选的关键字参数
optionflags
将模块常量进行或运算,默认为 0。可能的值(详见文档):DONT_ACCEPT_TRUE_FOR_1
DONT_ACCEPT_BLANKLINE
NORMALIZE_WHITESPACE
省略号
SKIP
IGNORE_EXCEPTION_DETAIL
REPORT_UDIFF
REPORT_CDIFF
REPORT_NDIFF
REPORT_ONLY_FIRST_FAILURE
可选的关键字参数
raise_on_error
在遇到第一个意外的异常或失败时引发异常。这允许对失败进行事后调试。可选的关键字参数
parser
指定一个 DocTestParser(或其子类),用于从文件中提取测试。可选的关键字参数
encoding
指定了一个编码,该编码应被用于将文件转换为unicode。高级恶作剧:testmod 运行本地 doctest.Tester 类实例的方法,然后将结果合并到(或创建)全局 Tester 实例 doctest.master 中。如果你想做一些不寻常的事情,也可以直接调用 doctest.master 的方法。在这种情况下,将 report=0 传递给 testmod 特别有用,可以延迟显示总结。完成后,调用 doctest.master.summarize(verbose)。
- sympy.testing.runtests.test(*paths, subprocess=True, rerun=0, **kwargs)[源代码][源代码]¶
在指定的 test_*.py 文件中运行测试。
如果在
paths
中的任何给定字符串与测试文件路径的一部分匹配,则运行特定 test_*.py 文件中的测试。如果paths=[]
,则运行所有 test_*.py 文件中的测试。注释:
如果 sort=False,测试将以随机顺序运行(非默认)。
路径可以以原生系统格式或unix的前斜杠格式输入。
黑名单中的文件可以通过提供其路径进行测试;只有在没有给出路径时,它们才会被排除。
测试结果说明
输出
意义
.
通过
F
失败
X
XPassed(预期失败但通过)
f
XFAILed(预期失败且确实失败)
s
跳过
w
慢
T
超时(例如,当使用
--timeout
时)K
KeyboardInterrupt(在运行
--slow
的慢测试时,您可以中断其中一个测试而不终止测试运行器)颜色没有额外的含义,仅用于帮助解释输出。
示例
>>> import sympy
运行所有测试:
>>> sympy.test()
运行一个文件:
>>> sympy.test("sympy/core/tests/test_basic.py") >>> sympy.test("_basic")
运行 sympy/functions/ 中的所有测试以及一些特定文件:
>>> sympy.test("sympy/core/tests/test_basic.py", ... "sympy/functions")
运行 sympy/core 和 sympy/utilities 中的所有测试:
>>> sympy.test("/core", "/util")
从文件中运行特定测试:
>>> sympy.test("sympy/core/tests/test_basic.py", ... kw="test_equality")
从任意文件运行特定测试:
>>> sympy.test(kw="subs")
以详细模式运行测试:
>>> sympy.test(verbose=True)
不要对测试输出进行排序:
>>> sympy.test(sort=False)
开启事后 pdb 调试:
>>> sympy.test(pdb=True)
关闭颜色:
>>> sympy.test(colors=False)
强制使用颜色,即使输出不是到终端(这很有用,例如,如果你正在将输出管道传输到
less -r
并且你仍然想要颜色)>>> sympy.test(force_colors=False)
回溯详细程度可以设置为“短”或“否”(默认是“短”)
>>> sympy.test(tb='no')
split
选项可以用来将测试运行分成多个部分。目前,分割仅限于测试文件,但未来可能会改变。split
应该是一个形式为 ‘a/b’ 的字符串,它将运行b
部分的第a
部分。例如,要运行测试套件的前半部分:>>> sympy.test(split='1/2')
time_balance
选项可以与split
一起传递。如果time_balance=True``(这是 ``sympy.test
的默认设置),SymPy 将尝试分割测试,使得每个分割部分花费相同的时间。这种平衡的启发式方法基于预先记录的测试数据。>>> sympy.test(split='1/2', time_balance=True)
你可以使用
subprocess=False
来禁用在一个单独的子进程中运行测试。这样做是为了支持哈希随机化种子,这在支持它的Python版本中是默认启用的。如果 subprocess=False,哈希随机化会根据调用Python进程中是否已启用而启用或禁用。然而,即使它被启用,种子也无法打印,除非它从一个新的Python进程中调用。哈希随机化在 Python 次版本 2.6.8、2.7.3、3.1.5 和 3.2.3 中被添加,并且在所有 Python 3.3.0 及之后的版本中默认启用。
如果哈希随机化不被支持,
subprocess=False
会被自动使用。>>> sympy.test(subprocess=False)
要设置哈希随机化种子,请在运行测试之前设置环境变量
PYTHONHASHSEED
。这可以通过在 Python 中使用以下方法完成>>> import os >>> os.environ['PYTHONHASHSEED'] = '42'
或者从命令行使用
$ PYTHONHASHSEED=42 ./bin/test
如果未设置种子,将选择一个随机种子。
请注意,要重现相同的哈希值,您必须使用相同的种子以及相同的架构(32位与64位)。