当前位置: 首页 > 面试题库 >

量角器的隐式等待与显式等待如何相互作用?

公孙阳文
2023-03-14
问题内容

当隐式等待少于显式等待时,就会发生误解:

var timeOut = 5000;
var search = element(by.xpath(`//*[@name='qwer']`));
browser.manage().timeouts().implicitlyWait(4000);
browser.ignoreSynchronization = true;

describe('Protractor Test', function () {
    beforeEach(function () {
        browser.get('https://www.google.com.ua');
    });
    it('EC', function () {
        console.log('START');
        // browser.sleep(timeOut);
        browser.wait(protractor.ExpectedConditions.presenceOf(search), timeOut);
    });
});

总时间:8.613秒。隐式设置等待第二个较低:3000,结果为6.865秒。它是如何工作的?预先感谢!


问题答案:

那是个好问题。许多优秀的QA自动化专家为此大吃一惊。

隐式等待

每个上都有特殊的隐藏自动等待driver.findElement(...)。如果在页面DOM结构中找不到元素,则原始Web驱动程序(js,python,java)会引发NoSuchElementException。driver.findElement无论您使用哪种定位器,这种等待都会在每个人之前完成。当隐式等待超时时,NoSuchElementException将被抛出findElement函数外。

启用隐式等待

默认情况下,隐式等待超时设置为0browser.manage().timeouts().implicitlyWait(3000)使网络驱动程序自动尝试/捕获此异常,然后重试以查找此元素。如果经过了3秒(超时),并且DOM中仍不存在element-
只有这样,您会收到NoSuchElementException。

好的时候:

您的页面修改了DOM结构(占网站的99.999%),并且某些元素仍然不在DOM中,但会在1-3秒内显示。为了不进行显式等待,并减少代码量-
您可以尝试设置隐式等待超时。

不好时: 您想测试DOM中不存在该元素。这种等待是在每次.findElement调用之前添加的,因此当您尝试这样声明时:

expect($('NON-EXIST-ELEMENT').isPresent()).toBeFalsy()

implicitWait还在这里工作。首先,您将等待3秒钟以使元素出现,然后将引发异常,并由isPresent()函数捕获,在这种情况下,该异常将返回false(我们实际声明的内容)。因此,您正在等待3秒!设置implicitWait(0)然后在断言元素不存在之后将其重新设置是有意义的(这可能确实很烦人)。

结束语
当您了解隐式等待的工作原理时,它就很好。我建议不要将隐式等待设置为超过1-5秒(您应该为每个网站定义自己的值)。同样,如果您计划声明许多不存在的元素-
将隐式等待重置为0,然后将其重新设置。

显式等待

您应该自己调用这种等待,但是它比隐式等待要灵活得多。在protractorjs中,当您需要等待时,必须调用browser.wait()。它接受谓词函数(该函数将仅返回true
/ false,无异常)。Webdriver将轮询此功能,直到发生超时(您将其指定为第二个参数)为止。您也可以将要抛出的错误消息指定为第三个参数。

显然,在Web自动化中,您通常会等待一些元素条件。为此,人们创建了谓词函数集合。此函数调用ExpectedConditions,并将为传递给它们的元素返回true
/ false。

browser.wait(ExpectedConditions.visibilityOf($('NON-EXISTING-ELEMENT')), 3000, 'error message')

何时好: 当您必须等待元素的一些棘手条件时。您可以轻松定义自己要等待的条件,指定自定义超时等等。在操作可能尚未准备就绪的元素之前使用。

不好的时候:
当您尝试通过结合使用browser.sleep(),隐式等待和显式等待来帮助您时。browser.sleep()默认情况下是不好的,在99%的情况下,您可以browser.wait()用提供的条件替换它,或者编写您自己的条件。

当您设置了隐式等待,并尝试调用显式等待时,会发生更多有趣的事情。想像:
browser.manage().timeouts().implicitlyWait(10000)
browser.wait(EC.stalenessOf($('NON-EXIST-ELEMENT')), 5000) //waiting for 5 seconds for element to disappear

这里发生的事情:等待stalenessOf()函数为您的元素调用函数。在里面,driver.findElement()被打了。隐式等待不要让此函数立即引发错误,并且将网页池化10秒钟,直到隐式等待超时发生为止,并且我们会收到NoSuchElementException异常。发生异常,执行返回到等待功能,已经过去了10秒钟!等待被TimeOutException终止,因为它只计划了5秒钟。等待时间比预期的要长得多,因此出现错误。

还请记住,JS是异步的,由于事件循环,不能保证确切的等待时间。通常,这会使等待时间不准确-5200毫秒而不是5000(例如)。这是完全不同的故事:)

您的示例中发生了什么

隐式超时-4000毫秒。

显式超时-5000毫秒。

  1. 等待开始。首次调用谓词功能-presenceOf()
  2. 内部谓词调用原始webdriverjs函数- driver.findElement(By.xpath('//*[@name='qwer']'))
  3. 由于设置了隐式等待,因此我们将在抛出错误之前等待它。
  4. 经过4000毫秒的隐式元素等待。只有现在,我们才将错误返回给谓词函数。
  5. 谓词函数捕获错误,并返回false
  6. 由于我们仍然有1000毫秒的明确等待超时时间-再次调用谓词函数。
  7. 隐式等待再次开始。4000毫秒后-将错误返回给谓词函数
  8. 谓词返回假
  9. 等待函数为假,并且我们的显式等待时间不够-在理想情况下-大约是8000毫秒,但还要注意异步调用,因此实时会更多
  10. 等待引发错误-jasminejs捕获错误,并且测试失败

我希望这个能帮上忙!



 类似资料:
  • 问题内容: 我在用: 但是对于以下元素它仍然连续失败 我添加了等待代码: 隐式等待是否应该等到找到一个元素后再进行处理?如果我使用而不是我添加的代码,还会更好吗? 问题答案: TL; DR:始终使用显式等待。忘记隐式等待的存在。 以下是显式等待与隐式等待之间的区别的简要概述: 显式等待: 记录和定义的行为。 在硒的本地部分运行(以你的代码语言显示)。 可以在你能想到的任何条件下工作。 返回成功或超

  • 驱动程序级别的隐式和显式等待之间有什么区别。哪一个是驱动级等待。如果我们在代码中提供隐式和显式等待。哪一个优先。

  • 我如何用一个显式的替换这个隐式的等待呢? driver=新ChromeDriver(功能); driver.manage().DeleteAllCookies();

  • 我正在尝试自动化基于共享点的应用程序,它有时会很慢。在下面的示例中,我试图将密码输入包装成显式等待。目前,Selenium以快速运行测试,导致无法执行操作。 如何将密码部分包装成硒显式方式?

  • 问题内容: 我正在学习Java Maven Selenium。我想要在Selenium中使用这样的东西。 打开网站(例如https://www.facebook.com) 单击登录的电子邮件字段 等待20秒 输入我的电子邮件 这是我的简单代码: 该代码不起作用。它只会打开Facebook,单击电子邮件字段并输入我的电子邮件ID,而不是等待10秒钟才输入我的电子邮件。 问题答案: 并且无法正常工作,

  • 问题内容: 这是我第一次使用selenium和无头浏览器,因为我想使用ajax技术来爬网某些网页。 效果很好,但是在某些情况下,加载整个页面会花费太多时间(尤其是当某些资源不可用时),因此我必须为selenium设置超时时间。 首先,我尝试了和,但是当我设置这些超时时,如果页面未完全加载,我将不会得到任何页面源,如下代码所示: 所以我尝试使用隐式等待和条件等待,如下所示: 这次我得到了想要的内容。