首页 > 解决方案 > 带有 Try Catch 的 while 循环在循环结束后抛出异常

问题描述

我正在使用 Nunit 和 C# 中的 selenium 编写一些网络测试我已经制作了一个导致一些奇怪行为的方法。

该方法的重点是尝试一些动作。

如果操作成功退出该方法。

如果操作引发异常,请等待 100 毫秒,然后重试。

如果该操作已尝试超过某个超时整数,则抛出超时异常。

如果操作引发异常,我还想添加一个选项来执行其他操作。

这是代码:

    public void Tryfor(Action tryAct, Action catchAct = null, int timeout = 50)
    {
        while (true) //loops until error or exception
        {
            Console.WriteLine(timeout); //For debugging
            if (timeout-- < 0) throw new TimeoutException("Tryfor timed out"); //reduce timeout by 1, when it reaches 0 throw exception
            try
            {
                tryAct();
                break; // If the try action succeeds with no exception, exit loop
            }
            catch   //If any exception is throw in the try action 
            {
                catchAct?.Invoke(); //If an action has been passed in the catch action, evoke it, else do nothing
            }
            Thread.Sleep(100); //wait 100 ms and try the try action again
        }
    }

这在大多数情况下都可以正常工作,但如前所述,它有时会以一种我无法真正理解的奇怪方式表现。

经常发生的情况是方法运行通过,可能在成功之前失败了 2 次。然后在成功后,它会抛出它捕获的所有错误。

更常见的是它达到了超时,这意味着它失败了(在这种情况下)50 次。然后,它不只是抛出超时错误,而是抛出它应该捕获的 50 个错误。

我的目标当然只是制作一种方法来完成我所描述的操作,但我真的很想了解它如何以及为什么会抛出它捕获的所有错误。

标签: c#seleniumloopstry-catchnunit

解决方案


根据您的评论,我看到您的某些操作包括断言,例如Assert.AreEqual.

当一个断言失败时,NUnit 会做两件事:

  1. 它记录失败。

  2. 它通过抛出异常来终止测试的执行。

如果你捕捉到异常,你会阻止第二步……测试不会终止。但是第一步已经开始了……失败已经报过了。

您的情况的解决方案是将所有断言移到操作之外,进入测试主体本身。例如,您可以断言没有引发异常。在动作中,抛出一些其他类型的异常......一个简单的System.Exception就可以了。例如,代替Assert.AreEqual(a, b),使用

if (a != b)
    throw new Exception("A was not equal to B");

只是不要显式地或通过 Assert 抛出任何 NUnit 异常。


推荐阅读