如何用doctest校验返回结果包含指定文本而非精确匹配
doctest 原生支持内容片段校验,无需切换正式单元测试框架
doctest 完全可以满足这类大返回值的片段校验需求,不需要额外换用unittest/pytest等正式单元测试框架。
它的核心运行逻辑是逐行执行文档字符串中标记的Python交互命令,只要执行过程没有抛出未预期的异常、命令的返回/打印结果和文档中标注的预期内容完全匹配,测试就会判定通过,从来没有要求必须把函数的完整返回值逐字写在测试用例里。
基础实现写法
针对HTML片段校验的需求,有两种非常简便的写法:
- 直接写成员判断表达式,显式标注预期返回值:
def fetch_large_html(): """ >>> html_res = fetch_large_html() >>> "<title>The Right Page</title>" in html_res True """ # 省略大体积HTML的拉取、处理逻辑 return "<html>......数百行内容......<title>The Right Page</title>......剩余内容......</html>"
- 用
assert断言写判断,写法更简洁:断言通过时不会产生任何输出,不需要额外写预期返回值;如果片段不存在,assert会抛出AssertionError,doctest会直接判定测试失败:
def fetch_large_html(): """ >>> html_res = fetch_large_html() >>> assert "<title>The Right Page</title>" in html_res """ # 省略大体积HTML的拉取、处理逻辑 return "<html>......数百行内容......<title>The Right Page</title>......剩余内容......</html>"
扩展校验能力
你完全可以在doctest里实现更灵活的校验逻辑,不受“完整匹配返回值”的限制:
- 支持多规则同时校验:可以在同一个测试块里写多条判断,同时校验多个关键片段是否存在、错误提示类内容是否不存在,比如:
""" >>> res = fetch_large_html() >>> assert "<h1>站点首页</h1>" in res >>> assert "<meta charset='utf-8'>" in res >>> assert "404 Not Found" not in res >>> assert "Server Error" not in res """
- 支持复杂逻辑校验:你可以在doctest块里导入需要的标准库/第三方库,实现正则匹配、HTML结构解析、返回值长度校验等各类判断,只要是Python交互Shell中可以执行的合法代码,基本都能在doctest中运行:
""" >>> import re >>> res = fetch_large_html() >>> # 用正则匹配动态变化的标题内容 >>> assert re.search(r"<title>.*?产品列表.*?第\d+页.*?</title>", res, re.S) """
注:很多人对doctest的认知存在误区,觉得它只能做死板的全值匹配,实际上它的灵活度足够覆盖大部分轻量测试场景,针对大返回值的片段校验是非常常规的用法。
内容的提问来源于stack exchange,提问作者machineghost
相关产品推荐
相关产品推荐

