2017-06-08 3 views
3

Ich habe die folgende benutzerdefinierte RetryAttribute aus diesem Beitrag genommen: NUnit retry dynamic attribute. Es funktioniert gut, aber wenn ich einen Timeout-Fehler in Selenium bekomme, funktioniert es nicht.C# - Selen - Retry Attribut arbeitet nicht mit Selenium Timeout

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

Retry benutzerdefiniertes Attribut:

/// <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) { 
    } 
} 

Und dann das benutzerdefinierte Attribut anwenden.

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

Wie kann das gelöst werden?

Antwort

3

Laut Dokumentation hier

NUnit Docs Retry Attribute

Wenn ein Test eine unerwartete Ausnahme hat, wird ein Fehler Ergebnis zurückgegeben und es erneut versucht wird, nicht. Nur Assertionsfehler können einen Wiederholungsversuch auslösen. Zu konvertieren Sie eine unerwartete Ausnahme in einen Assertionsfehler, siehe ThrowsConstraint.

Schwerpunkt meiner.

Der Zusammenhang ThrowsNothingConstraint behauptet einfach, dass die Delegierten keine Ausnahme werfen.

Sie müssen die Ausnahme abfangen und eine fehlgeschlagene Assertion verursachen, wenn keine Ausnahme erwartet wurde.

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

Also der obige Code sagt einfach ausführen die Aktion und es sollte keine Ausnahme erwarten. Wenn eine Ausnahme ausgelöst wird, handelt es sich um eine fehlgeschlagene Assertion. Der Wiederholungsversuch wird ausgeführt, wenn das Attribut auf den Test angewendet wird.

3

Eine andere Lösung wäre, Ihre eigene RetryAttribute zu implementieren, um die WebDriver-Ausnahme abzufangen. Auf diese Weise müssen Sie den Test nicht ändern:

[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 != ResultState.Failure) 
        break; 

       if (count > 0) 
        context.CurrentResult = context.CurrentTest.MakeTestResult(); 
      } 

      return context.CurrentResult; 
     } 
    } 

}