Unittest Framework 简明教程

UnitTest Framework - Doctest API

doctest API 围绕下列两个容器类进行,用于从 docstring 中存储交互示例 −

  1. Example − 一个单独的 Python 语句,与预期的输出配对。

  2. DocTest − 一个示例集合,通常从单个 docstring 或文本文件中提取。

定义了以下附加处理类,用于查找、解析并运行以及检查 doctest 示例 −

  1. DocTestFinder − 查找给定模块中的所有 docstring,并使用 DocTestParser 从包含交互示例的每个 docstring 创建一个 DocTest。

  2. DocTestParser − 从字符串(如某个对象的 docstring)创建 doctest 对象。

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

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

DocTestFinder Class

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

此类定义 find() 方法。它返回由对象的 docstring,或其包含对象的任何 docstring 定义的 DocTest 列表。

DocTestParser Class

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

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

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

  3. parse(string[, name]) - 将给定字符串划分为示例和干预文本,并将它们作为 Examples 和字符串的交替列表返回。 Examples 的行号采用 0 为基准。可选参数名称是一个标识此字符串的名称,并且仅用于错误消息。

DocTestRunner Class

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

report_start()

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

report_success()

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

report_failure()

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

report_unexpected_exception()

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

run(test)

运行测试中的示例(一个 DocTest 对象),并使用 writer 函数 out 显示结果

summarize([verbose])

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

OutputChecker Class

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

此类中定义了以下方法 -

check_output()

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

output_difference()

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

DocTest Integration with 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() 方法来执行它。

以下是用于从文本文件和包含 doctest 的模块创建 unittest.TestSuite 实例的两个主要函数 -

doctest.DocFileSuite()

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

doctest.DocTestSuite()

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

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

DocTestSuite() 在底层创建一个 unittest.TestSuite ,该对象由 doctest.DocTestCase 实例和 DocTestCase(unittest.TestCase 的子类)组成。

类似地,DocFileSuite() 使用 doctest.DocFileCase 实例创建一个 unittest.TestSuite,而 DocFileCase 是 DocTestCase 的子类。

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

但是,如果您正在编写一个 unittest 框架,unittest 最终会控制何时以及如何运行测试。框架作者通常想要控制 doctest 报告选项(例如,由命令行选项指定),但无法通过 unittest 将选项传递给 doctest 测试运行程序。