UnitTest 框架 - Doctest API

Doctest API 围绕以下两个容器类展开,用于存储来自文档字符串的交互式示例 −

  • 示例 − 单个 Python 语句,与其预期输出配对。

  • DocTest − 示例集合,通常从单个文档字符串或文本文件中提取。

以下附加处理类用于查找、解析和运行以及检查 doctest 示例 −

  • DocTestFinder −查找给定模块中的所有文档字符串,并使用 DocTestParser 从包含交互式示例的每个文档字符串创建 DocTest。

  • DocTestParser − 从字符串(例如对象的文档字符串)创建 doctest 对象。

  • DocTestRunner − 执行 doctest 中的示例,并使用 OutputChecker 验证其输出。

  • OutputChecker − 将 doctest 示例的实际输出与预期输出进行比较,并确定它们是否匹配。

DocTestFinder 类

它是一个处理类,用于从给定对象的文档字符串及其所包含对象的文档字符串中提取与给定对象相关的 doctest。目前可以从以下对象类型中提取 Doctests — 模块、函数、类、方法、静态方法、类方法和属性。

此类定义 find() 方法。它返回由 对象的 文档字符串或其所包含的任何对象的文档字符串定义的 DocTests 列表。

DocTestParser 类

它是一个处理类,用于从字符串中提取交互式示例,并使用它们创建 DocTest 对象。此类定义以下方法 −

  • get_doctest() − 从给定的字符串中提取所有 doctest 示例,并将它们收集到 DocTest 对象中。

  • get_examples(string[, name]) −从给定的字符串中提取所有 doctest 示例,并将它们作为 Example 对象列表返回。行号从 0 开始。可选参数 name 是标识此字符串的名称,仅用于错误消息。

  • parse(string[, name]) − 将给定的字符串分为示例和中间文本,并将它们作为交替的 Examples 和字符串列表返回。Examples 的行号从 0 开始。可选参数 name 是标识此字符串的名称,仅用于错误消息。

DocTestRunner 类

这是一个处理类,用于执行和验证 DocTest 中的交互式示例。其中定义了以下方法 −

report_start()

报告测试运行器即将处理给定的示例。提供此方法是为了允许 DocTestRunner 的子类自定义其输出;不应直接调用它。

report_success()

报告给定的示例已成功运行。提供此方法是为了允许 DocTestRunner 的子类自定义其输出;不应直接调用它。

report_failure()

报告给定的示例失败。提供此方法是为了允许 DocTestRunner 的子类自定义其输出;不应直接调用它。

report_unexpected_exception()

报告给定的示例引发了意外异常。提供此方法是为了允许 DocTestRunner 的子类自定义其输出;不应直接调用它。

run(test)

运行 test 中的示例(DocTest 对象),并使用编写器函数 out 显示结果。

summarize([verbose])

打印此 DocTestRunner 已运行的所有测试用例的摘要,并返回 命名元组 TestResults(failed, attempted)。可选的 verbose 参数控制摘要的详细程度。如果未指定详细程度,则使用 DocTestRunner 的详细程度。

OutputChecker 类

此类用于检查 doctest 示例的实际输出是否与预期输出匹配。

此类中定义了以下方法 −

check_output()

如果示例的实际输出 (got) 与预期输出 (want) 匹配,则返回 True。如果这些字符串相同,则始终认为它们匹配;但根据测试运行器使用的选项标志,也可能存在几种非精确匹配类型。有关选项标志的更多信息,请参阅选项标志指令部分。

output_difference()

返回一个字符串,描述给定示例的预期输出(example)与实际输出(got)之间的差异。

DocTest 与 Unittest 集成

doctest 模块提供了两个函数,可用于从包含 doctest 的模块和文本文件创建 unittest 测试套件。要与 unittest 测试发现集成,请在测试模块中包含一个 load_tests() 函数 −

import unittest
import doctest
import doctestexample

def load_tests(loader, tests, ignore):
   tests.addTests(doctest.DocTestSuite(doctestexample))
   return tests

将形成一个由 unittest 和 doctest 测试组成的 TestSuite,现在可以通过 unittest 模块的 main() 方法或 run() 方法执行。

以下是从文本文件和带有 doctests − 的模块创建 unittest.TestSuite 实例的两个主要函数

doctest.DocFileSuite()

它用于将一个或多个文本文件中的 doctest 测试转换为 unittest.TestSuite。返回的 unittest.TestSuite 将由 unittest 框架运行,并运行每个文件中的交互式示例。如果文件中的任何示例失败,则合成的单元测试失败,并引发 failureException 异常,显示包含测试的文件的名称和(有时是近似的)行号。

doctest.DocTestSuite()

它用于将模块的 doctest 测试转换为 unittest.TestSuite

返回的 unittest.TestSuite 将由 unittest 框架运行并运行模块中的每个 doctest。如果任何 doctest 失败,则合成的单元测试失败,并引发 failureException 异常,显示包含测试的文件的名称和(有时是近似的)行号

在幕后,DocTestSuite() 从 doctest.DocTestCase 实例中创建 unittest.TestSuite,DocTestCase 是 unittest.TestCase 的子类。

类似地,DocFileSuite() 从 doctest.DocFileCase 实例中创建 unittest.TestSuite,DocFileCase 是 DocTestCase 的子类。

因此,创建 unittest.TestSuite 的两种方式都会运行 DocTestCase 的实例。当您自己运行 doctest 函数时,您可以通过将选项标志传递给 doctest 函数来直接控制正在使用的 doctest 选项。

但是,如果您正在编写 unittest 框架,则 unittest 最终会控制测试的运行时间和方式。框架作者通常希望控制 doctest 报告选项(例如,可能由命令行选项指定),但没有办法通过 unittest 将选项传递给 doctest 测试运行器。