模拟“睡眠”

1 投票
2 回答
657 浏览
提问于 2025-04-17 20:50

我正在写一个应用程序,它会异步触发一些事件。测试的流程是这样的:先设置好一切,然后等一段时间,再检查事件是否触发。

不过因为要等,所以测试运行起来花费的时间比较长——每次测试我大约要等10秒。我觉得我的测试速度太慢了,虽然还有其他地方可以加快速度,但这个等待的部分显得最明显。

有没有什么办法可以去掉这个等待呢?有没有什么方法可以“作弊”一下时间或者类似的东西?

这个应用是基于tornado的网页应用,异步事件是通过IOLoop触发的,所以我没法直接触发它。

补充说明:更多细节。

这个测试是一种集成测试,我希望能够模拟第三方代码,但不想直接触发我自己的代码。

测试的目的是验证某个消息是否通过websocket发送,并且在浏览器中正确处理。消息是在客户端连接到websocket处理器的那一刻开始计时后发送的。超时时间是通过连接时的datetime.now()和数据库中的一个值之间的差值来计算的。这个值被人为设置为在使用selenium请求页面之前的datetime.now() - 5秒。因为加载页面需要一些时间,而且在不同的机器上可能会有点随机,所以我觉得减少这5秒的时间差并不是明智的选择。在超时后加载页面会产生不同的结果(不应该发送websocket消息)。

所以问题是,如何强制tornado的IOLoop在websocket连接后随时发送消息——如果在设置数据库值后的0.5秒内发生了这个事件,那我还要等4.5秒,我想尝试消除这个延迟。

两个明显可以模拟的地方是IOLoop本身和datetime.now()。现在的问题是,我应该选择哪个进行修改,以及该怎么做。

2 个回答

1

使用内置的 tornado 测试工具。每个测试都有自己的 IOLoop,你可以用 self.stopself.wait 来获取结果,比如(来自文档):

    client = AsyncHTTPClient(self.io_loop)
    # call self.stop on fetch completion
    client.fetch("http://www.tornadoweb.org/", self.stop)
    response = self.wait()
1

如果你想要模拟 sleep 这个功能,那么在你的应用代码里就不要直接使用它。我建议你创建一个类方法,比如 System.sleep(),然后在你的应用中使用这个方法。这样的话,System.sleep() 就可以被模拟了。

撰写回答