0

0

Python 如何写出可测试的函数

冰川箭仙

冰川箭仙

发布时间:2026-01-26 19:13:02

|

395人浏览过

|

来源于php中文网

原创

可测试函数需明确输入输出、无隐式依赖、无副作用、返回具体值、避免修改可变输入,优先纯逻辑测试而非过度mock。

python 如何写出可测试的函数

函数必须有明确的输入和输出

可测试的函数不能依赖全局状态或隐式环境,比如直接读配置文件、调用 time.time()、修改模块级变量。测试时你得能“喂”进去确定的输入,拿到确定的输出。

常见错误现象:test_get_user() 有时通过有时失败,因为函数内部调用了 datetime.now() 或读了本地 config.yaml;或者函数里写了 print()logging.info(),导致断言逻辑被干扰。

  • 把所有外部依赖抽成参数:时间用 now=None,配置用 config_dict=None
  • 避免在函数体内做 I/O(如 open()requests.get()),改用传入已准备好的数据或 mock 对象
  • 返回值要具体:别返回 None 表示成功,而用布尔值或枚举;别靠打印日志判断逻辑分支

避免副作用,尤其是修改传入的可变对象

如果函数接收一个 listdict 并直接修改它,测试时容易污染其他用例,也违背“输入确定 → 输出确定”的契约。

使用场景:比如写一个 add_tag(items, tag),本意是给每个 item 加个字段,但如果它直接 item["tag"] = tag,那测试完原数据就变了。

立即学习Python免费学习笔记(深入)”;

意兔-AI漫画相机
意兔-AI漫画相机

照片变漫画手绘,做周边好物

下载
  • 默认对可变参数做浅拷贝:items = items.copy()items = [dict(i) for i in items]
  • 更稳妥的做法是不修改输入,而是返回新结构:return [{"tag": tag, **item} for item in items]
  • 如果真需要原地修改,函数名必须明确体现副作用,比如叫 inplace_add_tag(),且文档注明“修改输入列表”

用类型提示 + 默认参数暴露行为边界

类型提示不是装饰,它是测试友好性的基础设施。IDE 和 mypy 能帮你提前发现传错类型的问题,更重要的是——测试用例写起来更有依据。

参数差异直接影响测试覆盖粒度。比如一个函数声明为 def parse_date(s: str, default: Optional[datetime] = None),你就知道至少要测:s 是空字符串、非法格式、合法 ISO 字符串;defaultNone 和非 None 两种路径。

  • 必填参数不设默认值(除非语义上确实可选),强迫调用方思考输入完整性
  • UnionOptional 显式表达可能的类型分支,避免运行时才抛 AttributeError
  • 复杂结构优先用 TypedDictdataclass 封装,比裸 dict 更易构造测试输入

测试时别绕过主逻辑去 mock 太深

有人为了“让测试快”,把函数里所有依赖都 mock 掉,结果实际函数体一行没跑,只验证了“是否调用了 mock”。这不是测试函数,是在测试调用顺序。

性能影响:过度 mock 可能让测试失去真实意义;兼容性影响:当底层接口变更(比如第三方库升级),mock 行为和真实行为脱节,测试照过但线上炸了。

  • 优先测试函数本身:给定输入,检查返回值是否符合预期
  • 只 mock 真正难控的部分(如网络、时间、随机数),且尽量用轻量方式,比如传 now=datetime(2020,1,1) 比 mock datetime 模块更安全
  • 如果函数必须调外部服务,把它拆成两层:纯逻辑函数 + 一个薄的胶水函数负责调 requests.post(),前者专注单元测试,后者走集成测试
测试真正难的不是写 assert,而是让函数足够“干净”到你能放心地断言。越早把副作用、隐式依赖、模糊边界从函数里剔出去,后面补测试的成本就越低。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

193

2023.09.27

python print用法与作用
python print用法与作用

本专题整合了python print的用法、作用、函数功能相关内容,阅读专题下面的文章了解更多详细教程。

19

2026.02.03

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1570

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

651

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

1228

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

1205

2024.04.29

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 5万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号