【问题标题】:Unit-testing a periodic coroutine with mock time使用模拟时间对周期性协程进行单元测试
【发布时间】:2015-11-26 13:56:43
【问题描述】:

我使用 Tornado 作为周期性进程的协程引擎,其中重复的协程在每次执行结束时对自身调用 ioloop.call_later()。我现在正在尝试通过单元测试(使用 Tornado 的 gen.test)来驱动它,我用局部变量 t 模拟 ioloop 的时间: DUT.ioloop.time = mock.Mock(side_effect= lambda: t) (DUT 被测设备) 然后在测试中,我手动增加 t 和 yield gen.moment 来踢 ioloop。这个想法是在不同的时间间隔后触发重复的协程,以便我可以验证它的行为。 但是协程并不总是触发 - 或者它可能会在完成执行之前返回到测试代码,从而导致失败。 我认为应该使用stop()wait() 来同步测试代码,但我无法具体看到如何在这种情况下使用它们。如果 DUT 在自己的 ioloop 中运行,那么整个测试策略如何工作?

【问题讨论】:

    标签: python unit-testing testing asynchronous tornado


    【解决方案1】:

    一般来说,使用yield gen.moment 来触发特定事件是冒险的;无法保证您必须等待多少“时刻”,或者触发事件发生的顺序。最好确保被测试的函数有一些可以异步等待的效果(如果自然没有这种效果,可以使用tornado.locks.Condition)。

    修补IOLoop.time 也有一些微妙之处。我认为它可以与默认的 Tornado IOLoops 一起使用(可以在不使用 mock 的情况下:在构造循环时传递 time_func 参数),但它不会产生预期的效果,例如AsyncIOLoop

    我认为您不想使用AsyncTestCase.stop.wait,但不清楚您的测试是如何设置的。

    【讨论】:

    • 谢谢本!我的被​​测函数在运行时可以发送一个 blinker.signal;这应该有助于同步测试,并且在其他方​​面也可能有用。
    猜你喜欢
    • 2018-11-27
    • 2020-05-07
    • 2019-12-17
    • 1970-01-01
    • 2015-03-06
    • 1970-01-01
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多