• 技术分享 | app自动化测试(Android)–显式等待机制


    WebDriverWait类解析

    WebDriverWait 用法代码

    Python 版本

    1. WebDriverWait(
    2. driver,timeout,poll_frequency=0.5,ignored_exceptions=None)

    参数解析:

    • driver:WebDriver 实例对象

    • timeout: 最长等待时间,单位秒

    • poll_frequency: 检测的间隔步长,默认为 0.5s

    • ignored_exceptions: 执行过程中忽略的异常对象,默认只忽略 TimeoutException 异常类

    Java 版本

    1. WebDriverWait(WebDriver driver, long timeOutInSeconds)

    Java 版本常用的有两个参数,参数解析:

    • driver:WebDriver 实例对象

    • timeOutInSeconds: 最长等待时间,单位秒

    until、util_not用法

    WebDriverWait 通常与 until 和 util_not 结合使用,Java 与 Python 用法相同。

    • until(method, message=’’) 在规定时间内,每隔一段时间调用一下 method 方法,直到返回值为 True,如果超时抛出带有 message 的 TimeoutException 异常信息

    • until_not(method, message=’’) 与 until( ) 方法相反,表示在规定时间内,每隔一段时间调用一下 method 方法,直到返回值为 False,如果超时抛出带有 message 的 TimeoutException 异常信息

    expected_conditions介绍

    expected_conditions 是 Selenium 的一个模块,其中包含一系列可用于判断的条件。可以用来判断页面的元素是否可见,是否可点击等操作。

    导入

    需要先导入这个模块,导入代码如下:

    • Python 版本:
    1. from selenium.webdriver.support import expected_conditions
    • Java 版本:
    1. import org.openqa.selenium.support.ui.ExpectedConditions;

    方法介绍

    1.判断元素是否被加到了 DOM 树里,并不代表该元素一定可见,用法如下:

    • Python 版本
    1. WebDriverWait().until(
    2. expected_conditions.presence_of_element_located(locator))
    • Java 版本
    1. new WebDriverWait( )\
    2. .until(ExpectedConditions.presenceOfElementLocated(locator));

    2.visibility_of_element_located(locator) 方法,用来判断某个元素是否可见(可见代表元素非隐藏,并且元素的宽和高都不等于 0,用法如下:

    • Python 版本
    1. WebDriverWait().until(
    2. expected_conditions.visibility_of_element_located(locator))
    • Java 版本
    1. new WebDriverWait( ).until(
    2. ExpectedConditions.visibilityOfElementLocated(locator));

    3.element_to_be_clickable(locator) 方法,判断某元素是否可见并能点击,用法如下:

    • Python 版本
    1. WebDriverWait().until(
    2. expected_conditions.element_to_be_clickable((By.ID, "kw")))
    • Java 版本
    1. new WebDriverWait( ).until(
    2. ExpectedConditions.elementToBeClickable(locator));

    案例

    使用“雪球”应用,打开雪球 APP,点击页面上的搜索输入框输入“alibaba”,然后在搜索联想出来的列表里面点击“阿里巴巴”,选择股票分类,获取股票类型为“09988”的股票价格,最后验证价格大于 170,核心代码如下:

    Python 版本

    1. ...
    2. def test_wait(self):
    3. # 点击搜索输入框
    4. self.driver.find_element_by_id(
    5. "com.xueqiu.android:id/tv_search").click()
    6. # 输入 “alibaba”
    7. self.driver.find_element_by_id(
    8. "com.xueqiu.android:id/search_input_text"
    9. ).send_keys("alibaba")
    10. # 点击“阿里巴巴”
    11. self.driver.find_element_by_xpath("//*[@text='阿里巴巴']").click()
    12. # 点击“股票”
    13. self.driver.find_element_by_xpath(
    14. "//*[contains(@resource-id,'title_container')]//*[@text='股票']"
    15. ).click()
    16. # 获取股票价格
    17. locator = (MobileBy.XPATH,
    18. "//*[@text='09988']/../../..\
    19. //*[@resource-id='com.xueqiu.android:id/current_price'")
    20. ele = WebDriverWait(self.driver,10)\
    21. .until(expected_conditions.element_to_be_clickable(locator))
    22. print(ele.text)
    23. current_price = float(ele.text)
    24. expect_price = 170
    25. # 判断价格大于 expect_price
    26. assert current_price > expect_price
    27. ...

    Java 版本

    1. ...
    2. private final By locator = By.xpath("//*[@text='09988']/../../..\
    3. //*[@resource-id='com.xueqiu.android:id/current_price'");
    4. @Test
    5. public void waitTest(){
    6. // 点击搜索输入框
    7. driver.findElementById("com.xueqiu.android:id/tv_search").click();
    8. // 输入 “alibaba”
    9. driver.findElementById("com.xueqiu.android:id/\
    10. search_input_text").sendKeys("alibaba");
    11. // 点击“阿里巴巴”
    12. driver.findElementByXPath("//*[@text='阿里巴巴']").click();
    13. // 点击“股票”
    14. driver.findElementByXPath("//*[contains(@resource-id,\
    15. 'title_container')]//*[@text='股票']").click();
    16. // 获取股票价格
    17. WebDriverWait wait=new WebDriverWait(driver, 10);
    18. wait.until(ExpectedConditions.elementToBeClickable(locator));
    19. String locatorText = driver.findElement(locator).getText();
    20. System.out.println(locatorText);
    21. float currentPrice = Float.parseFloat(locatorText);
    22. float expectPrice = 170;
    23. //判断价格大于 expect_price
    24. assertThat(currentPrice, greaterThan(expectPrice));
    25. }
    26. ...

    这条测试用例仅仅使用隐式等待是解决不了问题的,因为【当前价格】这个元素一直在,而实际需要等待的是这个元素是否处于可点击的状态。

    上面的代码通过判断元素是否可点击的方法来判断元素是否处于可点击状态,中间添加了 10 秒的等待时间,在 10 秒之内每隔 0.5 秒查找一次元素,如果找到了这个元素,就继续向下执行,如果没找到就抛出 TimeoutException 异常信息。显式等待可以在某个元素上灵活的添加等待时长,尤其是文件上传,或者资源文件下载的场景中,可以添加显式等待,提高脚本的稳定性。

    一般来说,在项目中会使用隐式等待与显式等待结合的方式,定义完 driver 之后立即设置一个隐式等待,在测试过程中需要判断某个元素属性的时候,再加上显式等待。

  • 相关阅读:
    【Flink】处理迟到元素(续)、自定义水位线和多流的合并与合流
    小红书母婴博主投放技巧是什么,怎么避免无用功
    见微知著,龙讯旷腾携全系列产品服务体系亮相2023工业软件生态大会
    Linux基础命令(示例代码 + 解释)
    常见的java面试题
    【华为OD机试真题 python】英文输入法 【2022 Q4 | 100分】
    Dubbo安装部署
    Javassist-ConstPool常量池
    Redis从入门到精通(三:常用指令)
    Mac搭建Java开发环境最佳指南
  • 原文地址:https://blog.csdn.net/hogwarts_beibei/article/details/125404347