Quelle est l'alternative à utiliser Thread.Sleep lorsque vous travaillez avec le sélénium dans les tests système?

StackOverflow https://stackoverflow.com/questions/9022293

Question

J'ai un testméthode utilisant le sélénium comme ci-dessous:

 [TestMethod]
        public void ShouldSendPasswordReminder()
        {
            // go to loginregister url
            _fireFoxWebDriver.Navigate().GoToUrl(UkPaBaseUrl + "loginregister.aspx");
            Thread.Sleep(1000);

            // click the forgotten password
            _fireFoxWebDriver.FindElement(By.LinkText("Forgotten your password?")).Click();
            Thread.Sleep(1000);

            // enter your email address

            _fireFoxWebDriver.FindElement(By.Id("PasswordResetRequest1_PasswordResetRequest_Username"))
                .SendKeys("username.lastname@domain.com");
            Thread.Sleep(1000);

            // click submit
            _fireFoxWebDriver.FindElement(By.Id("PasswordResetRequest1_PasswordResetRequest_PasswordResetRequestSubmit")).Click();
            Thread.Sleep(5000);

            // assert
            Assert.IsTrue(_fireFoxWebDriver.Url.Contains("ThankYou"));
        }

Comme vous pouvez le voir, je devrais appeler Thread.Sleep plusieurs fois (parce que la page pourrait prendre un certain temps pour terminer ce qu'il fait en raison de JavaScript, etc.) presque après chaque action parce que le sélénium ne semble pas être en mesure de gérer Page Charges et retards contrairement à Was.

Cela rend le code plutôt laid et pas très fiable.

Quelle est la meilleure façon de gérer de tels scénarios? Écrivez-vous également des appels de thread fréquents dans vos tests?

Merci,

Était-ce utile?

La solution

Vous pouvez utiliser les fonctionnalités de gestion pour définir le temps de ligne de base souhaité FindElement() attendre avant d'échouer:

_fireFoxWebDriver.Manage()
                 .Timeouts()
                 .ImplicitlyWait(TimeSpan.FromSeconds(1000));

Autres conseils

Attendre explicite. Selon la documentation officielle (http://www.seleniumhq.org/docs/0 ...), Thread.Sleep () est le pire des cas d'attente explicite.

Dans une attente explicite, sans attendre le temps maximum pour passer, il se déroule dès que la condition se produit, si cette condition se produit avant la fin du temps maximum spécifié. Par conséquent, avoir à attendre le temps maximum (car la condition ne s'est pas produite pendant le temps maximum spécifié) est le pire des cas d'attente explicite.

Je pense que Thread.Sleep () est considéré comme le pire cas d'attente explicite car, pour thread.sleep (), il doit attendre le temps plein spécifié comme argument de thread.sleep (), avant de continuer.

Vous pouvez penser pourquoi Thread.Sleep () n'est pas implicite. Je pense que c'est parce que l'effet de Thread.Sleep () n'est qu'à l'endroit où il est écrit, comme une attente explicite. L'effet de l'attente implicite est cependant pour toute la durée de vie de l'instance du conducteur.

**JAVA**
WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));

**C#**
using (IWebDriver driver = new FirefoxDriver())
{
driver.Url = "http://somedomain/url_that_delays_loading";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>(d => d.FindElement(By.Id("someDynamicElement")));
}

Cela attend jusqu'à 10 secondes avant de lancer un TimeoutException ou s'il constate que l'élément le retournera en 0 à 10 secondes.

Mon exemple de code, mon cas de test voulait que j'attende un maximum de 10 secondes, plus tôt j'attendais 10 secondes avant de trouver mon prochain élément en utilisant Thread.Sleep. Maintenant, j'utilise le WebDriverWait, donc si l'élément est trouvé, cela accélère mes activités quotidiennes et gagne également du temps.

using (IWebDriver driver = new ChromeDriver(options))
        {
            TimeSpan t = TimeSpan.FromSeconds(10);
            WebDriverWait wait = new WebDriverWait(driver,t);
            try
            {  
                driver.Navigate().GoToUrl("URL");
                //IWebElement username = driver.FindElement(By.Name("loginfmt"));
                IWebElement username = wait.Until(ExpectedConditions.ElementIsVisible(By.Name("loginfmt")));                                      
                username.SendKeys(dictionaryItem);
                //Thread.Sleep(10000); Removed my Thread.Sleep and tested my wait.Until and vola it works awesome.
                IWebElement next = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("idSIButton9")));
                //IWebElement nextdriver.FindElement(By.Id("idSIButton9"));
                next.Click();

Mon heuristique général sur l'introduction de retards lorsque mon script devient plus rapide que mon application est de vraiment penser à ce que j'attends. À mon avis, les appels de type sommeil ne sont vraiment appropriés que dans les cas où j'attends réellement le temps de s'écouler. Un cas où je testais un délai d'attente automatique pourrait être logique d'avoir un appel de type fil. Habituellement, cependant, j'attends que d'autres choses se produisent - les pages se chargent, JavaScript s'exécuter, etc. Dans ces cas, attendre une période de temps définie est un moyen facile de sembler dépasser la complexité potentiellement plus grande de la vérification pour ce que j'attends. Cela a cependant plusieurs pièges - vous pourriez ralentir trop vos tests (et si chacun de vos attentes au-dessus n'avait besoin que de 200 ms, par exemple - maintenant même le bref extrait ci-dessus prend 2,5 secondes supplémentaires (et c'est sans ajuster le 5 Deuxième attente à la fin). Cela peut ne pas sembler beaucoup par lui-même, mais cela s'additionne à mesure que votre suite grossit.) Un autre piège se produit lorsque vous vous déplacez vers une machine plus lente ou des choses environnementales ralentissent votre application - et si cela prenait 1,5 seconde Avant de pouvoir cliquer sur le mot de passe oublié? lien sur une machine. Votre test échouerait, mais cela peut toujours être dans des seuils de performances acceptables pour votre application, vous avez donc maintenant une fausse défaillance. Cela est souvent traité en augmentant simplement le temps d'attente, mais cela ramène au premier piège que j'ai mentionné à nouveau.

Pour sortir de ce cycle, je trouve qu'il est très important d'être aussi précis que possible lorsque j'attends des choses. Le sélénium fournit une classe d'attente qui peut être utilisée pour attendre qu'une condition particulière soit remplie. Je ne sais pas si les liaisons .NET l'incluent, mais je vais les utiliser en l'attendant. Dans la version Ruby, nous donnons à attendre un bloc de code - il peut rechercher la présence d'un élément ou tout ce que nous devons vérifier. La méthode d'attente prend une valeur de délai d'expiration et une valeur d'intervalle, puis exécute le bloc à chaque intervalle des secondes jusqu'à ce que le bloc renvoie vrai ou que la période de délai d'expiration se soit écoulée. La configuration d'une classe comme celle-ci vous permet de définir vos valeurs de délai suffisamment élevées pour gérer l'extrémité inférieure de l'échelle de performance, mais pas pour encourir la pénalité d'attendre beaucoup plus longtemps que vous en avez vraiment besoin dans une course donnée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top