【问题标题】:Pytest how to mock threading.TimerPytest如何模拟threading.Timer
【发布时间】:2019-01-12 10:18:56
【问题描述】:

我知道如何模拟当前时间,我已经尝试过了。问题是我的程序使用了threading.Timer,它似乎不受模拟时间的影响。

这个问题肯定发生过。我怎样才能“睡觉”我的单元测试或以某种方式模拟时间的流逝?

调用sleep 可能是个坏主意,因为实际执行速度取决于单元测试运行的硬件。

对这个问题有什么建议吗?

【问题讨论】:

  • 你知道如何模拟当前时间是什么意思?你能展示你的代码的相关部分吗?而且,您能否展示您的程序如何使用 threading.Timer?最后,您能解释一下您尝试通过测试实现的目标吗?
  • 程序使用定时器在 60 秒后执行一些任务。我需要测试该任务确实在 60 秒后执行。我想通过测量任务输出来实现这一点,而不是计算回调函数执行了多少次。计时器嵌入在更大的代码中。 (否则看起来我正在尝试测试计时器类本身。)

标签: python unit-testing pytest


【解决方案1】:

如果您查看the source for threading.Timer,您可以看到延迟效果来自Timer(它本身就是一个Thread)只是在.wait() 对象上调用.wait()

您可以使用unittest.mockpytest-mockEvent.wait() 实现替换为实际上不等待任何东西的实现。

【讨论】:

  • 虽然它可能会工作一段时间,但模拟(或修补)第三方库的内部结构会产生非常脆弱的测试。一旦 Thread 在内部停止使用 Event,您的测试就会中断,您将不知道为什么。我会非常小心这种方法。
  • @ierdna threading 不是第 3 方库。它是标准库的一部分。上次触及 Timer 类时was 8 years ago(用于更改文档字符串;implementation 已经 20 年没有改变),所以我不希望它很快改变实现。
  • 点了,在这种特殊情况下可能没问题;我想总的来说,我会告诫不要修补您不拥有源代码的组件的内部结构。
【解决方案2】:

更新:您的评论最终阐明了您打算实现的目标,即不必在测试中等待真正的 60 岁。关于如何对与计时器一起工作的代码进行单元测试的主题已经有一些讨论:

基本思想是,使用一种称为“控制反转”的技术:不要让被测系统 (SUT) 控制时间,而是更改设计以使测试能够做到这一点。有许多不同的方法,例如 a) 将计时器对象转换为参数,或者,b) 在 SUT 中以可以被测试覆盖的辅助方法访问它,或者让 SUT 从工厂获取它(您在测试期间替换它),或者,使测试可以用 setter 方法等覆盖它。

原始答案(侧重于不同方面):

根据您的问题和评论,我得出结论,对于您的测试,您接受测试的执行实际上需要大约 60 秒(引用您的话:“我需要测试该任务确实在 60 秒后执行。”和“如何我可以“睡觉”我的单元测试[...]”)。您想测试程序是否使用计时器来执行任务 - 这是一个集成测试场景而不是单元测试场景。

测试描述还不是很准确,所以我会做一些假设。假设您要测试“任务”是否未在 59 秒之前执行,但也不晚于 61 秒。有几种方法可以实现这一点。一种简单的方法是,实际使用睡眠 58 秒,检查任务是否尚未执行(测试用例 1),并有另一个睡眠 61 秒的测试用例并检查任务是否已执行。但是,由于各种影响,它并不完全稳健,正如您已经提到的。您可以通过扩大时间间隔使其更健壮。

另一种方法需要更改设计:在您的程序中,您在启动计时器之前立即读取时钟时间,并将此时间戳传递给您的计划任务。在计划任务中,第一件事是再次读取时钟。然后可以将该时间与其他时间戳进行比较。这些结果可用于测试,读取时间戳或增量。这可能更准确,但仍会受到例如操作系统引起的调度效应的影响。

我想说,因为这个问题是关于 python 程序的,所以你只能忍受一定程度的不准确。即使在具有 C 甚至汇编语言程序的实时系统中,达到高水平的准确度也是具有挑战性的 - 但我们在这里讨论的是不同水平的准确度(微秒甚至更高)。

【讨论】:

  • 问题不在于时间测量的准确性。问题是我不希望我的测试套件每次执行时都等待 59 或 61 秒。
  • 谢谢,我没有找到这些的原因是因为我正在寻找 python 特定的答案。感谢您将这些问题联系起来。
猜你喜欢
  • 2018-12-12
  • 2022-08-19
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多