【问题标题】:How to unit test a method that runs into an infinite loop for some input?如何对某个输入陷入无限循环的方法进行单元测试?
【发布时间】:2011-08-22 23:50:57
【问题描述】:

这个问题突然出现在我的脑海里,我想在这里问这个。

这种情况是故意的,我只是写了一个无限运行的循环。如何进行单元测试?

我问这个是因为,这种情况可能发生在代码的任何地方。说我的方法委托给其他几个方法,我想知道

  • 它是如何陷入无限循环的
  • 是哪组输入引起的
  • 调用哪个方法(从这个方法)导致了这个

我没有为此编写代码。这个问题纯粹是为了了解如果将来出现这种情况该怎么办。请回复。

【问题讨论】:

  • 无限循环是故意的吗?另外,谷歌“停止问题”。
  • 我可以从提出这个问题的人那里知道关闭的原因,为什么要关闭它?
  • @dlev,是的,这是故意的。当我想到可能发生这种情况的情况时,我突然想到了这一点
  • @Shankar:什么时候应该从该方法中检索结果?
  • @zerkms,我编辑了我的问题。请回复

标签: unit-testing junit tdd nunit infinite-loop


【解决方案1】:

如何对某个输入陷入无限循环的方法进行单元测试?

您可以测试几乎相反的结果:“如何对方法进行单元测试,以便该方法对于某些输入的运行时间不会超过 Xxxx 毫秒”。如果此测试失败,您可能已经找到了一个无限循环的候选者。

NUnit 2.5 有一个TimeoutAttribute,如果测试花费的时间超过给定的毫秒数,则测试失败。

【讨论】:

    【解决方案2】:

    让循环函数将循环检查委托给注入的依赖项:

    interface IShouldLoop
    {
        bool ShouldLoop();
    }
    
    class ClassToTest
    {
        private final IShouldLoop shouldLoop;
    
        public ClassToTest(IShouldLoop shouldLoop)
        {
            this.shouldLoop = shouldLoop;
        }
    
        public void MethodToTest()
        {
            while(shouldLoop.ShouldLoop())
            {
                // do whatever
            }
        }
    }
    

    您可以测试它是否每次都将循环检查委托给IShouldLoop 依赖项,并且您可以控制测试中的循环,以便它只循环您想要的次数。在生产环境中,使用始终返回 true 的 IShouldLoop 实例对其进行实例化。

    【讨论】:

    • 我喜欢这种方法。我认为LoopConditionisTrue() 这两个名字更有意义。
    • 另一种选择是将方法标记为虚拟并覆盖它以进行测试\
    【解决方案3】:

    unitesting 的目的是测试程序中每个最简单的单元。

    最简单的单元通常是一个执行单个任务的函数,所以为了统一你的无限循环,你必须提取这个循环可以在一个可以单独调用的单独函数中执行的每个任务,一旦完成了这个你将能够在给定所有可能参数的情况下调用这些函数,以测试您的函数应该能够处理的不同场景。作为一个函数的无限循环不必联合,但它内部的较小任务。

    【讨论】:

      【解决方案4】:

      我希望您的意思是某种消息泵/事件处理循环。 (大多数无限循环都很糟糕)。

      我会确保循环委托给某个处理输入的类。彻底测试这个类。

      循环构造失败的可能性很小。所以我会通过验收测试或手动进行测试。

      这有点类似于测试可执行文件的 Main 函数。这里的技巧也是确保 Main 委托给可测试的类。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-01-22
        • 1970-01-01
        • 1970-01-01
        • 2020-05-13
        相关资源
        最近更新 更多