C#-Selenium-Retry属性不适用于Selenium超时
我从这篇文章中获得了以下自定义内容:。它工作正常,但当我在Selenium中遇到超时错误时,它就不工作了C#-Selenium-Retry属性不适用于Selenium超时,c#,unit-testing,selenium,nunit,C#,Unit Testing,Selenium,Nunit,我从这篇文章中获得了以下自定义内容:。它工作正常,但当我在Selenium中遇到超时错误时,它就不工作了 WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5)); wait.Until(ExpectedConditions.ElementToBeClickable(element)); 重试自定义属性: /// <summary> /// RetryDynamicAttr
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) {
}
}
如何解决这个问题?根据此处的文档 努尼特医生 如果测试有意外异常,则返回错误结果并 它不会重试只有断言失败才能触发重试。到 将意外异常转换为断言失败,请参阅 我的 相关的代理只是断言委托 不会引发异常 您需要捕获异常,并在异常不是预期的情况下导致断言失败
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
Assert.That(() => {
wait.Until(ExpectedConditions.ElementToBeClickable(element));
}, Throws.Nothing);
因此,上面的代码只是说执行操作,它不应该期望出现异常。如果抛出异常,则它是一个失败的断言。如果属性应用于测试,则将执行重试。另一个解决方案是实现自己的
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;
}
}
}
[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;
}
}
}