news 2026/4/29 0:39:17

python doctest

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
python doctest

# Python doctest:被低估的文档测试利器

什么是doctest

说到Python的测试工具,大部分人第一反应是unittest或者pytest。但有个藏在标准库里的小家伙,经常被人忽略,它就是doctest。

简单来说,doctest允许你在文档字符串里写代码示例,然后自动验证这些示例是否正确运行。听起来很简单对吧?但这东西背后的设计思路其实挺有意思的——它把文档和测试绑在了一起,确保你文档里的例子永远是最新的。

举个例子,你去超市买牛奶,包装上写着“保质期7天”,结果拿回家发现其实已经过期了。这就像那些文档和实际代码不一致的情况。doctest就是要避免这种问题。

它能做什么

doctest的核心能力其实就两件事:验证文档中的代码示例是否正确,以及作为一个轻量级的测试框架使用。

但它的价值远不止这些。想象一下这样的场景:你写了一个函数,文档里贴心地给出了使用示例。六个月后,你修改了这个函数,但忘了更新文档。新来的同事看着你的文档示例运行出错,开始怀疑人生。doctest就在这种时刻发挥作用——它会在每次测试运行时,自动检查这些例子是否还能正常工作。

另外,doctest的交互性测试方式很特别。它模拟的是Python交互环境的样子,也就是说,你可以直接复制粘贴交互环境中的对话来创建测试。比如你在终端里试了一串代码:

>>> 1 + 2 3

这段对话就能直接成为doctest的测试用例。对于简单的函数或模块,这意味着你几乎不需要额外写测试代码。

怎么使用

用doctest其实很自然。假如你写了一个计算商品折扣的函数:

defcalculate_discount(price,discount_rate):""" 计算折扣后的价格 示例: >>> calculate_discount(100, 0.2) 80.0 >>> calculate_discount(50, 0.1) 45.0 """returnprice*(1-discount_rate)

运行测试的方式也简单,在模块末尾加两行:

if__name__=="__main__":importdoctest doctest.testmod()

然后执行这个模块,如果一切正常,什么都不会输出。有错误的话,会详细告诉你哪里出了问题。

doctest也支持更细致的控制。比如你想忽略某些行的输出差异,或者期望测试抛出异常。甚至可以测试包含随机值的示例,只要用上# doctest: +ELLIPSIS这样的指令。

最佳实践

这些年用了不少doctest,总结出几条经验:

第一个原则:用在合适的地方。doctest最适合那些简单的、有明确输出的函数。比如数据处理、字符串操作、数学计算这类。不适合用在那些涉及网络、数据库、随机数的地方——虽然也能测试,但会让文档看起来臃肿。

第二个原则:保持示例简洁。每条doctest用例只测试一个场景。见过有人在文档里写了一大段代码,测试了十几个不同的情况。这样做维护起来很痛苦,而且读者看着也累。真正的好文档,例子就该像教科书一样,一个点一个例子。

我自己的做法是:重要函数写两到三个典型例子,覆盖正常情况和边界情况。比如处理字符串的函数,会写一个正常输入、一个空字符串、一个特殊字符的例子。

第三个原则:把doctest当作“文档”来维护。经常有人把doctest写成理解测试,然后随意修改文档也不更新测试。实际上应该反过来——先想好文档里要展示什么例子,再把它们变成测试。这样文档和测试就自然统一了。

和同类技术对比

说完doctest,得聊聊它的竞争对手们。

首先是unittest。这是Python标准库里的正统测试框架。它的优势在于能力更强,可以做setUp、tearDown,支持测试套件、断言方法等。但缺点也很明显——你需要写单独的测试类和方法,对简单的小函数来说有点重。

打个比方,unittest像是给你的代码买了个保险柜,什么都能锁,但每次开锁都要费点功夫。doctest就像是贴了个防盗标签,轻便快捷,但只能防君子。

再说pytest。这货现在是Python测试的事实标准。它的能力远超doctest,支持参数化测试、fixture、插件系统等等。pytest也内置了对doctest的支持,可以在pytest框架下运行doctest。

有人问我为什么不用pytest完全替代doctest。我的回答是:doctest的独特价值在于“文档即测试”的理念。pytest虽然也能测试文档中的例子,但它做不到让代码示例和文档描述如此紧密地融合在一起。

最后说说Sphinx的doctest扩展。如果你在写项目文档,Sphinx可能是更好的选择。它能在构建文档时自动运行测试,而且支持更丰富的输出格式。不过对于小项目来说,标准库的doctest已经足够了。

一点个人见解

用了这么多年Python,我感觉doctest最容易被忽视的价值不是测试本身,而是它迫使你把代码的使用方式想得更清楚。当你需要在文档里写一个清晰可运行的例子时,你会不自觉地开始思考:这个API设计得是否直观?命名是否合理?用例是否覆盖了常见场景?

在这个意义上,doctest更像是个设计工具,而非测试工具。它让你在写代码的同时,就在为未来的用户着想。这一点,是unittest和pytest都做不到的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/29 0:33:40

量子计算技术路线与Shor算法实现挑战

1. 量子计算发展现状全景量子计算作为颠覆性计算范式,其核心在于利用量子比特(qubit)的叠加态和纠缠特性实现指数级并行计算能力。当前全球量子计算发展呈现出"技术路线多元化、应用探索加速化"的鲜明特征。根据2024年最新统计数据…

作者头像 李华
网站建设 2026/4/29 0:31:26

RedHat 9 新手避坑:手把手教你配置阿里云yum源,告别下载龟速

RedHat 9 新手避坑:手把手教你配置阿里云yum源,告别下载龟速 刚接触RedHat 9的新手开发者们,是否经常被软件包下载速度折磨得怀疑人生?官方源那堪比蜗牛的下载速度,简直能让急性子的人抓狂。别担心,今天我们…

作者头像 李华
网站建设 2026/4/29 0:27:10

[论文分享] ArXiv 提升LLMs推理能力之合成数据生成范式——Agentic Proposing

摘要速览 复杂推理能力的提升依赖大量高质量、可验证的训练数据,但人工标注成本高昂且难以规模化。现有数据合成方法面临两难权衡:有效性和难度——保证问题有效性则难度受限,放宽约束提升难度又容易产生逻辑矛盾甚至无解的问题。 为此&…

作者头像 李华
网站建设 2026/4/29 0:21:40

增量式知识图谱持续构建系统应用【附代码】

(1)面向火电厂故障文档的实体关系联合抽取模型: 针对故障文本中实体特征稀疏和实体嵌套问题,提出了一种融合双向编码表示与跨层记忆网络的关系抽取模型。采用预训练语言模型作为底层编码器,获取上下文相关的字向量表示…

作者头像 李华
网站建设 2026/4/29 0:20:35

HPH核心构造全解析:三大系统一看就懂

如今处于2026年4月28日,国家航天局已预先谋划布局太空制造等新的业态,商业航天正步入工业化量产阶段,精密设备的技术升级成为各个行业所关注的重点。在各种各样的工业装置里,HPH因自身构造极其精密,在食品药品、化妆品…

作者头像 李华