【问题标题】:C# - Selenium - Retry Attribute not working with Selenium timeoutC# - Selenium - 重试属性不适用于 Selenium 超时
【发布时间】:2017-11-10 08:23:47
【问题描述】:

我有以下自定义 RetryAttribute 取自这篇文章:NUnit retry dynamic attribute。它工作正常,但是当我在 Selenium 中遇到超时错误时,它不起作用。

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(ExpectedConditions.ElementToBeClickable(element));

重试自定义属性:

/// <summary>
/// RetryDynamicAttribute may be applied to test case in order
/// to run it multiple times based on app setting.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class RetryDynamicAttribute : RetryAttribute {
    private const int DEFAULT_TRIES = 1;
    static Lazy<int> numberOfRetries = new Lazy<int>(() => {
        int count = 0;
        return int.TryParse(ConfigurationManager.AppSettings["retryTest"], out count) ? count : DEFAULT_TRIES;
    });

    public RetryDynamicAttribute() :
        base(numberOfRetries.Value) {
    }
}

然后应用自定义属性。

[Test]
[RetryDynamic]
public void Test() {
    //.... 
}

如何解决?

【问题讨论】:

    标签: c# unit-testing selenium nunit


    【解决方案1】:

    另一种解决方案是实现您自己的RetryAttribute 来捕获WebDriver 异常。这样您就不必更改测试:

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
    public class RetryAttributeEx : PropertyAttribute, IWrapSetUpTearDown
    {
        private int _count;
    
        public RetryAttributeEx(int count) : base(count) {
            _count = count;
        }
    
        public TestCommand Wrap(TestCommand command) {
            return new RetryCommand(command, _count);
        }
    
        public class RetryCommand : DelegatingTestCommand {
    
            private int _retryCount;
    
            public RetryCommand(TestCommand innerCommand, int retryCount)
                : base(innerCommand) {
                _retryCount = retryCount;
            }
    
            public override TestResult Execute(TestExecutionContext context) {
    
                for (int count = _retryCount; count-- > 0; ) {
    
                    try {
                        context.CurrentResult = innerCommand.Execute(context);
                    }
                    catch (WebDriverTimeoutException ex) {
                        if (count == 0)
                          throw;
    
                        continue;
                    }
    
                    if (context.CurrentResult.ResultState.Status != ResultState.Failure.Status)
                        break;
    
                    if (count > 0)
                        context.CurrentResult = context.CurrentTest.MakeTestResult();
                }
    
                return context.CurrentResult;
            }
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      根据此处的文档

      NUnit 文档Retry Attribute

      如果测试出现意外异常,则返回错误结果并 它不会重试。 只有断言失败才能触发重试。到 将意外异常转换为断言失败,请参阅 ThrowsConstraint.

      强调我的。

      相关的ThrowsNothingConstraint 只是断言委托 不会抛出异常。

      如果没有预期的异常,您需要捕获异常并导致断言失败。

      WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
      Assert.That(() => {
               wait.Until(ExpectedConditions.ElementToBeClickable(element));
           }, Throws.Nothing);
      

      所以上面的代码只是说执行动作,它不应该期待异常。如果抛出异常,则它是一个失败的断言。如果属性应用于测试,将执行重试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-26
        • 2017-04-05
        • 2013-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-30
        • 1970-01-01
        相关资源
        最近更新 更多