在系统测试中使用Selenium时,Thread.Sleep的替代方法是什么?

3

我有一个使用Selenium的TestMethod,代码如下:

 [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调用吗?

谢谢。


这似乎是同一个问题 https://dev59.com/92025IYBdhLWcg3wqn4N - Sign
3个回答

3
您可以使用“管理”功能来设置在FindElement()失败之前要等待的基准时间:
_fireFoxWebDriver.Manage()
                 .Timeouts()
                 .ImplicitlyWait(TimeSpan.FromSeconds(1000));

有关其使用的更多信息,请查看官方文档 - dialex

2

显式等待。

根据官方文档(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秒,如果在0-10秒内找到了元素,则会返回该元素,否则会抛出TimeoutException异常。

我的样例代码,测试用例要求我最多等待10秒钟,在使用Thread.Sleep查找下一个元素之前,我之前一直在等待10秒钟。现在我使用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
我的一般启发是,当我的脚本比我的应用程序更快时,要考虑清楚我在等待什么。在我看来,sleep类型的调用只适用于我实际上正在等待时间流逝的情况下。如果我正在测试自动超时的情况下,可能需要在其中使用Thread.sleep类型的调用,因为我实际上正在等待特定的时间流逝。然而,通常情况下,我正在等待其他事情发生-页面加载、javascript执行等。在这些情况下,等待一段固定的时间是一个简单的方法,可以似乎克服检查我实际上在等待什么的潜在复杂性。但这有多个缺陷-你可能会使你的测试变得太慢(例如,如果你上面的每个等待只需要200毫秒,那么即使是上面的简短片段也需要额外的2.5秒(而且这还没有调整最后的5秒等待)。虽然单独看起来不算什么,但随着套件变得越来越大,它会累积。)另一个缺陷发生在你转移到较慢的机器或环境因素减慢了你的应用程序时-如果在一台机器上,在1.5秒之前你才能点击“忘记密码?”链接,你的测试将失败,但这可能仍然在你的应用程序可接受的性能阈值范围内,因此你现在有了一个虚假的失败。这通常通过简单地增加等待时间来解决,但这又回到了我之前提到的第一个缺陷。
为了打破这个循环,我发现在等待事物时尽可能具体非常重要。Selenium提供了一个Wait类,可以用于等待特定条件的满足。我不知道.Net绑定是否包括它,但我会期望使用它们。在Ruby版本中,我们给Wait一个代码块-它可以查找元素的存在或任何其他需要检查的内容。wait方法接受超时值和间隔值,然后每隔interval秒运行一次该块,直到块返回true或超时期已过。设置这样的类允许您将超时值设置得足够高,以处理性能范围的低端,但不会因在给定运行中等待比实际需要更长时间而产生惩罚。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接