跳至内容

Faketime

Faketime 是一个围绕优秀的 C 库 libfaketime(由 Wolfgang Hommel 编写)的轻量级 Python 包装器,你可以用它来欺骗 UNIX 进程关于时间和日期。

为什么存在这个包装器?

  • 它提供了一个方便且 Pythonic 的接口,你可以用它来欺骗使用 Python 运行的子进程。
  • 它提供了一个 Python 接口,在 Mac OS X 和 Linux 上都相同(libfaketime 在两者上的使用方式略有不同)。
  • 它提供了一个自包含的库,可以安装在虚拟环境中,并在任何环境中一致地运行 - 从包管理器安装 libfaketime 可能会在不同的操作系统和包管理器上获得旧的、有问题的版本。

安装

pip install faketime

使用

>>> from commandlib import Command
>>> from faketime import Faketime
>>> from datetime import datetime
>>> faketime = Faketime("currenttime.txt")
>>> datecmd
{'LD_PRELOAD': '/full/path/to/virtualenv/site-packages/faketime/libfaketime.so.1', 'FAKETIME_TIMESTAMP_FILE': '/full/path/to/currenttime.txt'}


>>> datecmd = Command("date").with_env(**faketime.env_vars)
>>> datecmd.run()
[ should print current time ]

>>> faketime.change_time(datetime(2050, 6, 7, 10, 9, 22, 713689))
>>> datecmd.run()
Tue  7 Jun 10:09:21 BST 2050

上面的示例展示了如何将 faketime 与 commandlib 一起使用,尽管字典中的环境变量可以与任何命令运行器一起使用(例如 Popen)。

这个库背后的故事是什么?

这个库可以用于多种目的,但我主要构建它是为了用 hitchstory 编写测试,这些测试会同时欺骗 postgres、django 和 celery 关于日期和时间。

最初,我尝试使用 freezegun 来测试 Python 代码,但我意识到它一次只能在一个代码片段上工作。而且

  • 如果该代码执行了一个包含其他代码的 Python 进程,那么其他代码将获得当前时间,而不是冻结时间,从而破坏了测试。
  • 它根本无法伪造,比如 postgres 的时间,所以如果一个 SQL 查询嵌入了日期时间查询,那么就会破坏测试。