FreezeGun:让 Python 测试在时间里自由穿行
FreezeGun:让 Python 测试在时间里自由穿行
FreezeGun 是一个 Python 测试工具库,在 GitHub 上收获了 4,514 个 Star。

测试里跟时间打交道是件麻烦事。日期变化、定时任务、超时逻辑,这些场景在测试中很难模拟。FreezeGun 解决的就是这个问题:把时间「冻住」,让被测代码永远停留在你指定的那一刻。
它的核心逻辑很直接。通过 mock Python 标准库的 datetime 模块,datetime.datetime.now()、datetime.date.today()、time.time() 等调用全部返回固定时间。time.monotonic() 和 time.perf_counter() 也会被冻结。

使用方式
FreezeGun 提供了三种调用方式,覆盖不同测试场景。
装饰器模式最常用。在测试函数或测试类上加一行 @freeze_time(“2012-01-14”),函数内所有时间相关调用都会返回这个日期:
from freezegun import freeze_time
@freeze_time("2012-01-14")
def test():
assert datetime.datetime.now() == datetime.datetime(2012, 1, 14)
上下文管理器适合只在代码块内冻结时间:
def test():
with freeze_time("2012-01-14"):
assert datetime.datetime.now() == datetime.datetime(2012, 1, 14)
需要更精细控制时,可以用 start/stop 手动管理:
freezer = freeze_time("2012-01-14 12:00:01")
freezer.start()
freezer.stop()
时区与时间推进
通过 tz_offset 参数设置时区偏移,datetime.now() 返回的是本地时间,datetime.date.today() 也会随之变化。这对跨时区应用很实用。
tick=True 让时间从冻结点继续走动,而不是静止。auto_tick_seconds 参数可以设定每次调用自动前进的秒数,模拟真实时间流逝。
frozen_datetime.move_to() 支持跳转到任意时间点,配合 tick() 方法可以逐秒推进,适合测试超时重试这类逻辑。
real_asyncio=True 让 asyncio 的事件循环使用真实时间,避免 asyncio.sleep() 被冻结后卡死。
忽略特定包
有些库内部依赖时间模块,冻结后可能导致异常。FreezeGun 提供了 ignore 参数:
with freeze_time('2020-10-06', ignore=['threading']):
...
默认已忽略 nose、django、selenium、pytest 等常用库。也可以通过 configure() 自定义忽略列表:
import freezegun
freezegun.configure(extend_ignore_list=['tensorflow'])
安装
pip install freezegun
FreezeGun 是 Python 测试生态里一个很实用的工具。它只做一件事,做得够简单够稳。项目里有跟时间打交道逻辑的话,值得一试。
FreezeGun 是 Python 测试生态里一个很实用的工具。它只做一件事,做得够简单够稳。项目里有跟时间打交道逻辑的话,值得一试。
更多推荐



所有评论(0)