Python 库手册:doctest 文档测试模块

doctest 是 Python 内置的测试模块,它能提取文档字符串(docstring)中的交互式示例,并自动运行这些示例以验证它们是否按预期工作。换言之,它将 Python 文档中的示例代码当作测试用例来运行,确保文档与实现保持一致。

这种"文档即测试"的理念非常适合函数库开发、教学案例、API 文档等场景。

常见应用场景:

(1)在函数 docstring 中嵌入交互式 Python 示例。

(2)编写代码说明时,自动验证示例代码的正确性。

(3)教学材料中自动检测代码段是否可运行。

(4)用作轻量级单元测试,快速验证函数行为。

◆ ◆ ◆

核心概念

1、示例格式

doctest 使用 Python 交互式解释器风格的语法:

python 复制代码
def add(a, b):    """    返回两个数的和。
    示例:    >>> add(2, 3)    5    >>> add(-1, 1)    0    """    return a + b

上例中的 >>> 表示输入,下一行是期望的输出。doctest 会解析这些片段并在执行时对比实际输出与期望输出。

2、测试执行方式

方式一:在脚本中添加运行代码:

javascript 复制代码
if __name__ == "__main__":    import doctest    doctest.testmod()

方式二:命令行运行:

nginx 复制代码
python -m doctest -v your_module.py

3、doctest 的核心思想是:将测试代码写进函数的 docstring 中,而不影响函数本身逻辑。

被测试的函数无需导入 doctest。

只有在运行测试的时候,才需要导入并调用 doctest 模块。

python 复制代码
# 测试驱动脚本(需要 import doctest)# test_mymath.pyimport mymathimport doctest
doctest.testmod(mymath)

这使得 doctest 非常适合做"文档即测试"的轻量级验证工具。

或者,在你的模块末尾加入以下代码,使得可以直接运行模块进行测试:

javascript 复制代码
if __name__ == "__main__":    import doctest    doctest.testmod()

◆ ◆ ◆

应用举例

例 1:函数中的内嵌测试

python 复制代码
def square(n):    """    返回平方值
    >>> square(2)    4    >>> square(-3)    9    """    return n * n
if __name__ == "__main__":    import doctest    doctest.testmod()

例 2:检查列表返回值

python 复制代码
def even_numbers(n):    """    返回不大于 n 的所有偶数。
    >>> even_numbers(6)    [0, 2, 4, 6]    """    return [i for i in range(n + 1) if i % 2 == 0]

例 3:浮点数精度控制

python 复制代码
def divide(a, b):    """    >>> divide(1, 3)    0.333...    """    return a / b
if __name__ == "__main__":    import doctest    doctest.testmod(optionflags=doctest.ELLIPSIS)

例 4:外部文档测试

将测试写在 .txt 或 .rst 文档中:

javascript 复制代码
>>> from math import sqrt>>> sqrt(9)3.0

运行测试:

javascript 复制代码
import doctestdoctest.testfile("test_math.txt")

例 5:捕捉异常

python 复制代码
def inverse(x):    """    >>> inverse(2)    0.5    >>> inverse(0)    Traceback (most recent call last):        ...    ZeroDivisionError: division by zero    """    return 1 / x

◆ ◆ ◆

常用函数速览

doctest.DocTestSuite()

从模块中提取测试并返回一个 unittest.TestSuite 对象。

参数:

module:模块对象或模块名

返回:一个可用于 unittest 的测试套件

doctest.ELLIPSIS(常量)

允许在期望输出中使用 ... 匹配任意文本。

用途:浮点数等不稳定输出的测试中

doctest.testfile(filename, ...)

运行指定文本文件中的 doctest 示例。

参数:

filename:文档文件名(如 test.txt)

module_relative:是否以模块路径解析文件名,默认 True

返回:运行结果 (失败数, 测试数) 元组

doctest.testmod(module=None, ...)

运行模块中的所有 docstring 测试。

参数:

module:默认为 main,也可传入模块对象

verbose:是否输出详细测试信息

optionflags:控制匹配选项,如 doctest.ELLIPSIS

返回:运行结果 (失败数, 测试数) 元组

◆ ◆ ◆

补充说明

1、多数 doctest 示例写在函数 docstring 中,也可以写在模块、类、方法的 docstring 中。

2、doctest 与 unittest 可结合使用,也可将其测试套件集成进更复杂的测试框架。

3、遇到多行输出时,输出格式必须与实际一致,空格、换行不可出错。

4、输出结果为字符串对比,注意类型/格式完全一致。

"点赞有美意,赞赏是鼓励"

相关推荐
IT_Octopus4 小时前
【零基础入门 LLM 开发 · Day 13】:LangChain 的对话记忆——Message 对象版
人工智能·python·langchain
2603_965148115 小时前
社区与学习资源:从入门到精通的API选品学习路径
数据库·人工智能·python·学习·数据挖掘
程序猿追5 小时前
kotlin-retry 接入鸿蒙后,怎样确认它真的会停止重试
开发语言·kotlin·harmonyos
我是人✓6 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
智能直播6 小时前
网络RTMP拉流不卡顿、声音不同步,一文讲透缓冲区、时间戳
开发语言·ffmpeg·php·音视频·视频编解码
CCblandy6 小时前
令牌桶在 0.9 倍负载超发 19%、固定窗口边界放行 20 个:四种限流算法同构实测
后端·python·算法·性能优化·架构
墨云安全6 小时前
内网资产无法暴露到公网,怎么做安全检测?2026 年内网渗透测试的落地路径
开发语言·安全·网络安全·渗透测试·php
摇滚侠7 小时前
《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 9 章 机器码与汇编语言 阅读笔记 9
java·开发语言·笔记
Cc.Y7 小时前
Java零基础入门:深入Java核心:文件IO与序列化全解
java·开发语言·python
拿本唠嗑AI研究7 小时前
本体工程实战指南:从建模到可维护的完整落地路径
java·人工智能·python·jena·ontology