Какая альтернатива использовать Thread.Sleep при работе с Selenium при тестировании системы? - PullRequest
3 голосов
/ 26 января 2012

У меня есть TestMethod, использующий Selenium, как показано ниже:

 [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"));
        }

Как вы можете видеть, мне пришлось бы вызывать Thread.Sleep много раз (потому что для завершения работы страницы может потребоваться некоторое время)из-за javascript и т. д.) почти после каждого действия, потому что Selenium, по-видимому, не в состоянии обрабатывать загрузки страниц и задержки в отличие от WatiN.

Это делает код довольно уродливым и не очень надежным.

Какой лучший способ справиться с такими сценариями?Вы часто пишете сообщения Thread.Sleep в своих тестах?

Спасибо,

Ответы [ 3 ]

3 голосов
/ 26 января 2012

Вы можете использовать функцию управления, чтобы установить базовое время, которое вы хотите FindElement() ждать, прежде чем произойдет сбой:

_fireFoxWebDriver.Manage()
                 .Timeouts()
                 .ImplicitlyWait(TimeSpan.FromSeconds(1000));
2 голосов
/ 22 декабря 2016

Явное ожидание. Согласно официальной документации (http://www.seleniumhq.org/docs/0...), Thread.sleep () - наихудший случай явного ожидания.

При явном ожидании, не дожидаясь истечения максимального времени, оно продолжается, как только возникает условие, если это условие возникает до того, как истечет указанное максимальное время. Следовательно, ожидание максимального времени (поскольку условие не произошло в течение указанного максимального времени) является наихудшим случаем явного ожидания.

Я думаю, что Thread.sleep () считается наихудшим случаем явного ожидания, потому что для Thread.sleep () он должен ждать все время, указанное в качестве аргумента Thread.sleep (), прежде чем продолжить .

Вы можете подумать, почему Thread.sleep () не является неявным ожиданием. Я думаю, что это потому, что эффект Thread.sleep () находится только в том месте, где он написан, как явное ожидание. Однако эффект неявного ожидания распространяется на весь срок службы экземпляра драйвера.

**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")));
}

Это ожидает до 10 секунд, прежде чем выдать TimeoutException или если он найдет, что элемент вернет его через 0 - 10 секунд.

В моем примере кода, в моем тестовом примере я ждал максимум 10 секунд, раньше я ждал 10 секунд, прежде чем нашел следующий элемент с помощью Thread.Sleep. Теперь я использую WebDriverWait, поэтому, если элемент найден, он продолжается, это ускоряет мою повседневную деятельность, а также экономит время.

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();
0 голосов
/ 26 января 2012

Моя общая эвристика при введении задержек, когда мой сценарий работает быстрее, чем мое приложение, заключается в том, чтобы действительно думать о том, чего я жду.На мой взгляд, вызовы типа «сон» действительно уместны только в тех случаях, когда я действительно жду, когда пройдет время.Случай, когда я тестировал автоматический тайм-аут, может иметь смысл иметь вызов типа Thread.sleep, потому что я на самом деле жду, пока не истечет определенное количество времени.Обычно, однако, я жду, когда произойдут другие вещи - загрузки страниц, выполнение javascript и т. Д. В этих случаях ожидание заданного периода времени - это простой способ преодолеть потенциально большую сложность проверки.за то, что я на самом деле жду.Однако здесь есть несколько ловушек - вы можете слишком сильно замедлять свои тесты (например, если каждое из ваших ожиданий выше должно составлять, например, 200 мс), теперь даже краткий фрагмент выше занимает дополнительные 2,5 секунды (и это без настройки 5).второе ожидание в конце). Это само по себе может показаться не таким уж большим, но оно увеличивается по мере того, как ваш пакет становится больше.) Еще одна ловушка возникает, когда вы переходите на более медленную машину или окружение замедляет работу вашего приложения - что, если это заняло 1,5 секундыпрежде чем вы сможете нажать Забыли пароль?ссылка на одну машину.Ваш тест не пройден, но он все еще может находиться в допустимых пределах производительности вашего приложения, поэтому у вас теперь есть ложный сбой.Это часто решается простым увеличением времени ожидания, но это приводит к первой ловушке, которую я снова упомянул.

Чтобы вырваться из этого цикла, я считаю очень важным быть максимально конкретным, когда яЯ жду вещей.Selenium предоставляет класс Wait, который можно использовать для ожидания выполнения определенного условия.Я не знаю, включает ли это привязки .Net, но я бы хотел использовать их, ожидая этого.В версии Ruby мы даем Wait блок кода - он может искать наличие элемента или что-либо еще, что нам нужно проверить.Метод wait принимает значение тайм-аута и значение интервала, а затем запускает блок каждые интервалы секунд, пока либо блок не вернет истину, либо период тайм-аута не истек.Настроив такой класс, вы сможете установить значения тайм-аута достаточно высокими, чтобы обрабатывать нижний предел шкалы производительности, но не понести наказание за ожидание намного дольше, чем вам действительно нужно в данном прогоне.

...