什么';在系统测试中使用Selenium时,可以选择使用Thread.Sleep

本文关键字:选择 Sleep Thread Selenium 系统测试 什么 | 更新日期: 2023-09-27 18:21:27

我有一个使用硒的测试方法,如下所示:

 [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电话吗?

谢谢,

什么';在系统测试中使用Selenium时,可以选择使用Thread.Sleep

您可以使用管理功能来设置您希望FindElement()在失败前等待的基线时间:

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

显式等待。根据官方文件(http://www.seleniumhq.org/docs/0...),Thread.sleep()是显式等待的最坏情况。

在显式等待中,在不等待最长时间结束的情况下,如果条件在指定的最长时间之前发生,则在条件发生时立即进行。因此,必须等待到最长时间(因为在指定的最长时间内没有出现这种情况)是显式等待的最坏情况。

我认为Thread.sleep()被认为是显式等待的最糟糕情况,因为对于Thread.sleen(),它必须等待指定为Thread.sleee()参数的完整时间,然后才能继续。

你可能会想为什么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")));
}

这将在抛出TimeoutException之前等待10秒,或者如果它找到元素,将在0-10秒内返回它。

我的示例代码,我的测试用例希望我最多等待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();

当我的脚本比我的应用程序更快时,我引入延迟的一般启发是真正思考我在等待什么。在我看来,只有在我真的在等待时间流逝的情况下,睡眠型电话才是合适的。在我测试自动超时的情况下,可能有一个Thread.sleep类型的调用,因为我实际上在等待一段特定的时间。然而,通常情况下,我会等待其他事情发生——要加载的页面、要执行的javascript等等。在这些情况下,等待一段时间似乎是一种简单的方法,可以克服检查我实际在等待什么的潜在更大复杂性。不过,这有多个陷阱——你可能会把测试速度放慢太多(例如,如果你的每个等待时间只需要200ms怎么办?现在,即使是上面的简短片段也需要额外的2.5秒(这还没有调整最后的5秒等待时间)。这本身可能看起来不算多,但随着你的套房越来越大,它会累积起来。)另一个陷阱发生在你移动到速度较慢的机器或环境因素减慢你的应用程序时——如果你花了1.5秒才点击"忘记你的密码"怎么办?一台机器上的链接。你的测试会失败,但这可能仍然在你的应用程序可接受的性能阈值内,所以你现在有一个错误的失败。这通常通过简单地增加等待时间来解决,但这又回到了我再次提到的第一个陷阱。

为了打破这种循环,我发现在等待的时候尽可能具体是非常重要的。Selenium提供了一个Wait类,可用于等待,直到满足特定条件。我不知道.Net绑定是否包括它,但我会在预期的情况下使用它们。在Ruby版本中,我们给Wait一个代码块,它可以查找元素的存在或我们需要检查的任何其他内容。wait方法获取一个超时值和一个间隔值,然后每隔几秒运行一次块,直到块返回true或超时时间结束。通过设置这样的类,您可以将超时值设置得足够高,以处理性能级别的低端,但不会因为在给定的运行中等待的时间过长而受到惩罚。