我已经为客户构建了一个付费的 CMS + 发票系统,我需要更加严格地进行测试。
我将所有数据保存在 Django ORM 中,并有一堆 Celery 任务以不同的时间间隔运行,以确保在用户不支付发票时发送新发票和发票提醒并切断访问权限。
例如,我希望能够运行以下测试:
创建一个新用户并为访问该网站的 X 天生成一张发票
模拟 X + 1 天的过去,并运行我在 Celery 中设置的所有任务。
检查是否已向用户开具另外 X 天的新发票。
到目前为止,我提出的 KISS 方法是在单独的机器上进行所有测试,并在操作系统级别实际操作日期/时间。所以测试脚本会:
将系统日期设置为第 1 天
创建一个新用户并为 X 天的访问生成第一张发票
提前 1 天然后系统日期。运行我所有的 celery 任务。重复直到 X + 1 天“过去”
检查是否已开具新发票
这有点笨拙,但我认为它可能会起作用。关于如何完成它还有其他想法吗?
最佳答案
您可以使用 mock更改用于获取时间的函数的返回值(例如 datetime.datetime.now
)。
有多种方法可以做到这一点(请参阅模拟文档),但这里有一种:
import unittest
import datetime
from mock import patch
class SomeTestCase(unittest.TestCase):
def setUp(self):
self.time = datetime.datetime(2012, 5, 18)
class fakedatetime(datetime.datetime):
@classmethod
def now(cls):
return self.time
patcher = patch('datetime.datetime', fakedatetime)
self.addCleanup(patcher.stop)
patcher.start()
def test_something(self):
self.assertEqual(datetime.datetime.now(), datetime.datetime(2012, 5, 18))
self.time = datetime.datetime(2012, 5, 20)
self.assertEqual(datetime.datetime.now(), datetime.datetime(2012, 5, 20))
因为我们不能直接替换 datetime.datetime.now
,所以我们创建了一个假的 datetime 类,除了在 now 被调用时返回一个常量值之外,所有的事情都是一样的。
关于python - 模拟单元测试中的时间流逝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10652097/