讲师中心 微信公众号
AI工具推荐 视频效率加速

Python 测试中时间与随机性的控制

风丽酱_8745

风丽酱_8745

发布时间:2026-02-16 11:19:35

|

153人浏览过

|

来源于php中文网

原创

pytest中mock时间函数失效因补丁位置错误:须patch被测模块内导入的名称,如import time则patch'your_module.time.time',from datetime import datetime则patch'your_module.datetime.now';freezegun需配对start/stop或用上下文管理器;random.seed()需每测试显式调用并兼顾numpy等库。

python 测试中时间与随机性的控制

pytest 中 mock time.time() 和 datetime.now() 为什么总失效

因为没打对补丁位置。Python 的时间函数被调用时,实际引用的是模块内导入的路径,不是你直觉里“写在哪就 patch 哪”的地方。

常见错误现象:patch('time.time') 没用,但测试里明明 import 了 time;或者 patch 了 datetime.datetime.now,结果被测代码里用的是 from datetime import datetime; datetime.now() —— 这时候得 patch 所在模块里的 datetime 名字,不是 datetime.datetime。

  • 查被测代码第一行 import:如果写的是 import time,patch 目标是 your_module.time.time
  • 如果写的是 from datetime import datetime,patch 目标是 your_module.datetime.now(注意不是 datetime.datetime.now)
  • 用 @patch 时,优先用装饰器作用于测试函数,比在 setUp 里手动 start/stop 更可靠
  • 示例:
    @patch('myapp.utils.datetime')
    def test_something(self, mock_dt):
        mock_dt.now.return_value = datetime(2023, 1, 1, 12, 0)
        # ……

用 freezegun 控制时间但测试跑完时间没恢复

freezegun 默认在测试函数退出后自动解冻,但一旦用了 freeze_time().start() 手动控制,就必须配对调用 .stop(),否则后续测试可能拿到冻结后的时间戳,导致断言失败或随机性残留。

使用场景:需要跨多个函数、或在异步/多线程中维持同一时间点;或者想在测试中间临时“跳时间”。

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

python学习
python学习

Python 编程学习助手 skill,面向零基础用户。 当用户表达以下意图时触发: - 学习 Python 基础概念(变量、数据类型、循环、函数、类等) - 请求 Python 练习题或测验 - 请求审查或调试 Python 代码 - 请求 Python 项目实战指导(爬虫、数据分析、Web 开发等入门项目) - 泛化表述如"教我 Python""我想学编程""Python 怎么写""帮我学 Python" 此 skill

下载
  • 避免直接用 freeze_time(...).start(),优先用上下文管理器:
    with freeze_time("2023-01-01 12:00:00"):
        assert my_func() == "morning"
  • 如果必须手动 start/stop,确保放在 try/finally 里,哪怕测试抛异常也能 cleanup
  • 注意 freeze_time 对 time.sleep() 无效——它不加速也不跳过 sleep,只是让 time.time() 返回固定值
  • 某些旧版 freezegun 在 pytest 参数化测试中会漏 cleanup,升级到 1.2.0+ 可缓解

random.seed() 不够用?为什么每次测试还是得到不同结果

因为 seed 只影响当前线程的随机状态,而测试框架(尤其是 pytest-xdist)可能并行跑多个测试,各在线程里重置 seed 后仍可能互相干扰;更隐蔽的是,第三方库(比如 numpy、uuid)内部也用随机数,它们不认 Python 的 random.seed()。

性能影响不大,但可靠性差:看似设了 seed,实际结果不可重现。

  • 全局设 seed 不够,应在每个测试开头显式调用 random.seed(42),且确保它在所有随机操作之前执行
  • 若用到 numpy.random,额外加 np.random.seed(42);若用 secrets 或 uuid.uuid4(),它们不支持 seed,只能 mock 或替换为确定性实现
  • 更稳的做法:用 random.Random(42) 实例,传给依赖它的函数,而不是污染全局状态
  • 示例:
    rng = random.Random(42)
    result = pick_random_item(items, rng=rng)

测试里生成“稳定随机字符串”却忘了长度和字符集约束

很多人用 random.choice(string.ascii_letters) 拼接字符串,以为设了 seed 就万事大吉,结果发现生成的字符串长度不一致、含意外字符(比如换行符)、甚至触发被测逻辑里的边界判断失败。

这不是随机性问题,是生成逻辑没对齐业务假设。

  • 别拼接,用 random.choices(population, k=n),它允许重复且长度严格可控;random.sample() 不重复但要求 population ≥ k
  • 字符集务必显式定义:string.ascii_lowercase + string.digits 比 string.printable 安全得多
  • 如果被测代码对字符串长度敏感(比如 token 截断、数据库字段限制),测试数据长度必须固定,不能依赖 random.randint(5, 12)
  • 示例:
    def make_token():
        chars = string.ascii_letters + string.digits
        return ''.join(random.choices(chars, k=16))

事情说清了就结束

热门AI工具

更多
Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6639

2023.08.02

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

14166

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

1685

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

3897

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

6061

2024.03.01

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

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

1798

2023.08.03

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

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

2804

2023.09.04

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

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

6144

2023.10.24

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

60

2026.10.22

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn