【问题标题】:Mocking "sleep"嘲讽“睡觉”
【发布时间】:2014-03-05 18:41:07
【问题描述】:

我正在编写一个异步触发某些事件的应用程序。测试看起来像这样:设置一切,休眠一段时间,检查事件是否已触发。

但是,由于等待测试需要很长时间才能运行 - 我在每次测试中等待大约 10 秒。我觉得我的测试很慢 - 还有其他地方可以加快它们的速度,但这种睡眠似乎是加快速度的最明显的地方。

消除睡眠的正确方法是什么?有什么方法可以欺骗 datetime 或类似的东西吗?

该应用程序是基于 Tornado 的 Web 应用程序,并且异步事件是通过 IOLoop 触发的,所以我没有办法自己直接触发它。

编辑:更多细节。

测试是一种集成测试,我愿意mock 3rd 方代码,但不想直接触发我自己的代码。

测试是验证某条消息是使用websocket发送的,并在浏览器中被正确处理。消息在客户端连接到 websocket 处理程序时启动的特定超时后发送。超时值取为连接时的datetime.now() 与数据库中的值之差。在使用 selenium 请求页面之前,该值被人为设置为datetime.now() - 5 seconds。由于加载页面需要一些时间,并且在不同的机器上可能有点随机,我认为减少 5 秒的时间间隔并不明智。超时后加载页面会产生不同的结果(不应发送 websocket 消息)。

所以问题是在 websocket 连接后的任何时刻以某种方式强制龙卷风的 IOLoop 发送消息 - 如果在设置数据库值后 0.5 秒内发生这种情况,则需要等待 4.5 秒,我想尝试消除它延迟。

两个明显的模拟位置是 IOLoop 本身和 datetime.now()。现在的问题是我应该修补哪一个以及如何修补。

【问题讨论】:

    标签: python tdd tornado


    【解决方案1】:

    如果你想模拟sleep,那么你不能直接在你的应用程序代码中使用它。我会创建一个像System.sleep() 这样的类方法并在你的应用程序中使用它。 System.sleep() 可以被嘲笑。

    【讨论】:

    • 问题是我使用的框架做了所有的调度,我真的不知道它是怎么做的。不过,理论上我可以用我自己的模拟替换它。
    【解决方案2】:

    使用内置的tornado testing tools。每个测试都有自己的 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()
    

    【讨论】:

    • 我认为仍然值得使用 AsyncHTTPTestCase 和 self.stop/self.wait。看看 Tornado 如何测试网络套接字:github.com/facebook/tornado/blob/master/tornado/test/…
    • 啊,我明白了。不过,进行测试的最快方法仍然是使用回调——设置页面并在发送 Web 套接字消息后执行回调,此时您可以检查结果。
    • 可以。但是消息被触发的时间呢?它计划在某个时间间隔后发送,这就是客户端等待的原因。
    • 是什么导致了那里的延迟?是预设的时间间隔吗?有什么办法可以缩短测试时间?
    • 所以,我会尝试这样做: 1. 在没有事件的情况下设置数据库 2. 加载页面 3. 检查数据(确认页面已加载) 4. 进行查询以触发 Web 套接字更改 5. 检查数据(确认已发送 Web 套接字消息)
    猜你喜欢
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 1970-01-01
    • 2016-02-22
    • 2014-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多