说‘不道德!`冻结你的测试

immobilus的Python项目详细描述


Download from PyPIbuildBuild status

一个简单的python测试时间冻结工具。它嘲笑:

  • datetime.date.today()
  • datetime.datetime.now()
  • datetime.datetime.utcnow()
  • datetime.datetime.fromtimestamp()
  • time.time()
  • time.gmtime()
  • time.localtime()
  • time.strftime()
  • time.mktime()

用法

您必须在datetimetime或任何 依次导入它们的其他模块,以允许它拦截那些 模块。

>>>fromimmobilusimportimmobilus>>>fromdatetimeimportdatetime,timedelta

例如,如果使用 pytest,您可以添加 import immobilus进入根文件conftest.py

上下文管理器

您可以使用immobilus作为上下文管理器。当上下文管理器 处于活动状态,时间将冻结到指定值。上下文之外 经理,使用原始的标准库函数 行为正常。

>>># It is unlikely that you are living in the past>>>datetime.utcnow()==datetime(2017,10,20)False>>># But with immobilus, you can pretend that you are>>>withimmobilus('2017-10-20'):...datetime.utcnow()==datetime(2017,10,20)...True>>># Once the context manager exits, immobilus deactivates.>>># We are back in the present.>>>datetime.utcnow()==datetime(2017,10,20)False

指定冻结时间

如上所示,可以使用字符串来描述要冻结的时间 (例如'2017-10-20')。任何价值观 dateutil.parser 可以使用。

您还可以使用datetime.datetime对象作为冻结时间:

>>>naive_freeze_time=datetime(2017,10,20)>>>withimmobilus(naive_freeze_time):...print('now:    %s'%datetime.now())...print('utcnow: %s'%datetime.utcnow())...now:2017-10-2000:00:00utcnow:2017-10-2000:00:00

immobilus将使用给定的datetime对象设置冻结 UTC时间本地时间与您提供的值相同。如果 datetime您提供的冻结时间是已知的,那么它是 调整为UTC,如下所示:

>>>importpytz>>>>>># Freeze to 12:00 noon in Moscow (UTC+3)>>>timezone=pytz.timezone('Europe/Moscow')>>>aware_freeze_time=timezone.localize(datetime(2017,10,20,12))>>>withimmobilus(aware_freeze_time):...# 9:00am local time which is same as UTC...print('now:    %s'%datetime.now())...print('utcnow: %s'%datetime.utcnow())...now:2017-10-2009:00:00utcnow:2017-10-2009:00:00

如果希望本地时间与UTC时间不同,请继续阅读。

冻结不是UTC时间的本地时间

若要在时间冻结时使其他时区生效,请使用 immobilus上下文管理器的第二个参数:tz_offset。 这是冻结的UTC时间之前的小时数 当地时间应该是。

>>>withimmobilus('2017-10-20 09:00',tz_offset=3):...print('now:    %s'%datetime.now())...print('utcnow: %s'%datetime.utcnow())...now:2017-10-2012:00:00utcnow:2017-10-2009:00:00

当然,如果您愿意,可以使用否定的 号码:

>>>withimmobilus('2017-10-20 09:00',tz_offset=-7):...print('now:    %s'%datetime.now())...print('utcnow: %s'%datetime.utcnow())...now:2017-10-2002:00:00utcnow:2017-10-2009:00:00

您可以通过调用tick方法来移动冻结的时间点:

>>>withimmobilus('2019-08-21 12:00:00')asdt:...print(datetime.now())...dt.tick()...print(datetime.now())...dt.tick(timedelta(seconds=10))...print(datetime.now())...2019-08-2112:00:002019-08-2112:00:012019-08-2112:00:11

用作装饰

除了作为上下文管理器,immobilus也是一个装饰器:

>>>@immobilus('2017-10-20')...deftest():...print(datetime.now())...>>>test()2017-10-2000:00:00

它甚至适用于类

>>>@immobilus('2017-10-20')...classDecorated(object):...now=datetime.utcnow()......deffirst(self):...returndatetime.utcnow()......defsecond(self):...returnself.now...>>>d=Decorated()>>>assertd.first().strftime('%Y-%m-%d %H:%M:%S')=='2017-10-20 00:00:00'>>>assertd.second().strftime('%Y-%m-%d %H:%M:%S')!='2017-10-20 00:00:00'

和协作(从python 3.5开始)

>>>importsys>>>importsix>>>>>>ifsys.version_info[0:2]>=(3,5):...result=''...six.exec_("""
... import asyncio
...
... @immobilus('2017-10-20')
... async def test():
...    return datetime.now()
...
... loop = asyncio.new_event_loop()
... result = loop.run_until_complete(test())
...     """)...assertresult.strftime('%Y-%m-%d %H:%M:%S')=='2017-10-20 00:00:00'

直接使用

或者您可以手动激活和停用immobilus

>>>freeze_time=datetime(2017,10,20)>>>spell=immobilus(freeze_time)>>>datetime.utcnow()==freeze_timeFalse>>>spell.start()FakeDatetime(2017,10,20,0,0)>>>datetime.utcnow()==freeze_timeTrue>>>datetime.utcnow()FakeDatetime(2017,10,20,0,0)>>>spell.stop()>>>datetime.utcnow()==freeze_timeFalse

这对使用标准库的用户非常有用 unittest.TestCase例如

importunittestclassSomeTests(unittest.TestCase):defsetUp(self):spell=immobilus('2017-10-20')spell.start()self.addCleanup(spell.stop)

嵌套

您还可以嵌套上下文管理器(或装饰器,或直接 调用,或任何组合)如果要冻结不同的时间。

>>>withimmobilus('2017-10-20 12:00'):...print('outer now:    %s'%datetime.now())...print('outer utcnow: %s'%datetime.utcnow())...withimmobilus('2017-10-21 12:00',tz_offset=5):...print('inner now:    %s'%datetime.now())...print('inner utcnow: %s'%datetime.utcnow())...print('outer now:    %s'%datetime.now())...print('outer utcnow: %s'%datetime.utcnow())...outernow:2017-10-2012:00:00outerutcnow:2017-10-2012:00:00innernow:2017-10-2117:00:00innerutcnow:2017-10-2112:00:00outernow:2017-10-2012:00:00outerutcnow:2017-10-2012:00:00

特别感谢您的贡献:

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java查找url是否引用现有对象   从IDEA到GitHub的java共享项目:如何将所有项目添加到名为“lab1”的分支中的存储库中   C++上java的崩溃   java mybatis从结果集创建临时表   多线程为什么在关闭Java执行器时要保留中断状态?   java MongoDB Spring批量插入多个文档的速度很慢   java如何在JOGL中旋转圆柱体   程序运行后的inputstream“java.util.NoSuchElementException未找到行”   java发送带有位图的彩信源代码   如何在java中通过逐字符添加字符从字符数组创建字符串   Eclipse RCP应用程序的java共享工作区   java如何使用点击式侦听器转到不同的xml布局?   Tomcat 7上面向java的DB JDBC连接器池   java如何创建你管格式的媒体播放器?   JMeter代理记录的java问题   java使用逗号拆分数据集<Row>上的字符串列,并获取新数据集<Row>   java Spring安全方法级别权限不起作用   java无法从远程maven存储库下载源代码,但可以从本地下载   do while Java:IndexOutOfBoundsException的不可预测性   Java iOS MDM:APNs证书UID更改