为什么不';t NUnit超时属性工作

本文关键字:超时 属性 工作 NUnit 为什么不 | 更新日期: 2023-09-27 18:27:00

我试图在Visual Studio中的测试中使用NUnit Timeout属性,但它似乎不起作用。我预计这个测试会失败,但它会运行20秒,然后通过。

为什么它不失败?

namespace Tests
{
    using System.Threading;
    using NUnit.Framework;
    [TestFixture]
    public class timeout_tests
    {
        [Test, Timeout(1)]
        public void timeout_test()
        {
            Thread.Sleep(20000);
        }
    }
}

我尝试了NUnit.framework.dll 3.0.0版本和最新版本3.0.1。两种版本的测试都在20秒后通过。

为什么不';t NUnit超时属性工作

事实证明,使用较旧的NUnit测试适配器(例如2.0.0.0版本),测试在20秒后通过,这不是预期的结果。

在移除旧适配器并安装NUnit3测试适配器之后,现在测试立即失败,这是预期的结果。

这似乎在最新版本的NUnit适配器2.1.1中得到了修复。

不过,我个人被这样一个事实愚弄了:我很快就向Console发送了大量输出(我相信这是适配器在output窗口中捕获的)。这在输出中创建了一种"返回日志",.NET希望在测试退出之前完成发送它收到的输出。您可以通过以下测试模拟这种行为:

[Test, Timeout(10000)] // Time out in 10 seconds
public void Test_MyFunction_DoesNotRunForever()
{
    DateTime start = DateTime.Now;
    while (true)
    {
        TimeSpan runTime = DateTime.Now - start;
        System.Diagnostics.Debug.WriteLine("Doing stuff for " + runTime.TotalSeconds + " seconds." + (runTime.TotalSeconds > 10 ? " Buggy! :(" : ""));
    }
}

如果你观察它的运行,你会注意到即使几分钟过去了,它仍然像Doing stuff for 2.043 seconds.一样打印输出

如果你不想减少输出,你应该通过一些适当的人工减速来降低输出,比如Thread.Sleep,最好是在不改变代码的情况下。即使是Thread.Sleep(1)也足以防止这种积压。脑海中浮现的一些选项:

  • 如果你有mock,你可以在mock的一个回调中稍作停顿
  • 重新组织代码以接受一个输出接收器作为参数,这样您就可以提供一个存根,添加一个短暂的停顿,然后传递输出