APP自动化测试-Appium元素定位之元素等待

本文详细介绍了在Appium自动化测试中元素等待的重要性,包括显式等待和隐式等待的使用方法,以及如何通过WebDriverWait设置等待条件,确保元素加载完成再进行操作,以提高测试效率和稳定性。
摘要由CSDN通过智能技术生成

一、什么是元素等待

元素等待的意义

  • 在 Appium 自动化测试中,元素等待是一个重要的环节。当脚本执行速度较快,而页面元素尚未加载完成时,就会导致脚本无法定位到元素,从而使执行失败。因此需要设置元素等待,从而增强脚本的健壮性,提高执行效率。
  • 元素等待的主要目的是确保在执行操作之前,目标元素已经在界面上可用。这样可以避免因元素未加载完成而导致的错误。

在使用元素等待时,需要注意以下几点

  • 等待时间的设置要合理,过长的等待时间会影响测试效率,过短可能导致等待失败。
  • 对于一些复杂的页面或网络环境较差的情况,可能需要适当增加等待时间。

以下是一些常见的元素等待方法:

  • WebDriverWait:可以设置等待时间和超时时间,在指定时间内等待元素出现。
  • 显式等待:通过明确指定要等待的条件来等待元素。
  • 隐式等待:在查找元素时设置一个全局的等待时间,在该时间内查找元素。

二、元素等待的方法

方法一

定义方法:
from selenium.webdriver.support.ui import WebDriverWait


# 定义一个获取元素的方法
def get_element(driver, element):
    wait = WebDriverWait(driver, 10, 1)
    # element = wait.until(lambda x: x.find_element(element[0], element[1]))
    element = wait.until(lambda x: x.find_element(*element))
    return element
方式解释:

这段代码是在使用 Selenium 库中的 WebDriverWait 类。

  • WebDriverWait(driver, 10, 1):创建一个等待对象 wait。其中:
    • driver:驱动对象。
    • 10:表示等待的最大时间(以秒为单位)。
    • 1:表示每隔 1 秒检查一次条件。
  • wait.until(lambda x: x.find_element(*element)):使用 until 方法等待某个条件满足。这里的条件是通过一个 lambda 函数定义的,该函数使用 driver 对象的 find_element 方法来查找指定的元素。

这段代码的目的是在最多等待 10 秒的时间内,每隔 1 秒检查一次,直到找到指定的元素。找到元素后,将其赋值给 element 变量。

通过设置等待时间和超时时的时间间隔,可以在执行操作之前确保网页已经加载完成,或者特定元素已经处于可用状态。

这样可以避免在元素尚未准备好时尝试与之交互而导致的错误。

方法应用:

下面是一个示例,使用上述显示等待的方法获取元素后,即使不使用time.sleep()方法进行等待,代码仍然可以正常执行:

import time
from appium import webdriver
from appium.options.android import UiAutomator2Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


# 定义一个获取元素的方法
def get_element(driver, element):
    wait = WebDriverWait(driver, 10, 1)
    element = wait.until(lambda x: x.find_element(*element))
    return element


# 定义一个初始化APP的方法
def start_app(app_package, app_activity):

    # 定义desired_caps 字典,初始化app的配置信息
    desired_caps = {
          "platformName": "android",  # 表示的是android
          "platformVersion": "10",  # 表示的是设备系统的版本号
          "deviceName": "DWV6R19A10002101",  # 表示的是设备的ID名称
          "appPackage": app_package,  # 表示的是app的包名
          "appActivity": app_activity,  # 表示的是app的界面名
          "newCommandTimeout": 100000,
          "noReset": True
    }
    # 创建 Appium 驱动实例
    options = UiAutomator2Options().load_capabilities(desired_caps)
    driver = webdriver.Remote("http://localhost:4723/wd/hub", options=options)

    # 启动应用程序
    driver.wait_activity(desired_caps, 5)

    # 返回驱动实例
    return driver


if __name__ == "__main__":
    # 本次启动的应用程序包名和活动名(作业帮)
    app_package_zyb = "com.baidu.homework"
    app_activity_zyb = ".activity.index.IndexActivity"

    # 启动应用程序
    driver_zyb = start_app(app_package_zyb, app_activity_zyb)

    # 通过元素id来进行元素定位,定位到作业批改年级选择框并点击
    grade_element = (By.ID, "com.baidu.homework:id/user_grade")
    grade_select = get_element(driver_zyb, grade_element)
    if grade_select.is_displayed():
        grade_select.click()
        print("grade_select clicked")
    else:
        print("grade_select not found or not displayed")

    # 通过XPATH来进行元素定位,定位到六年级并点击,设置年级成功
    grade_xpath = By.XPATH, "//android.widget.TextView[@resource-id='com.baidu.homework:id/gradeName' and @text='六年级']"
    grade_set = get_element(driver_zyb, grade_xpath)
    if grade_set.is_displayed():
        grade_set.click()
        print("grade_set clicked")
    else:
        print("grade_set not found or not displayed")

    # 通过CLASS_NAME定位到"我的"并点击,进入我的tab页
    # 下面代码如果不加上time.sleep()可能会报错,可以使用方法二来避免
    time.sleep(3)
    class_path = By.CLASS_NAME, "android.widget.ImageView"
    may_tab = get_element(driver_zyb, class_path)
    if may_tab.is_displayed():
        may_tab.click()
        print("may_tab clicked")
    else:
        print("may_tab not found or not displayed")

    # 停止应用程序,退出驱动
    time.sleep(5)
    print("代码执行结束")
    driver_zyb.quit()

方法二

定义方法:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


# 定义一个获取元素的方法
def get_element_new(driver, element):
    element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located(element))
    return element
方法解释:

这段代码是在使用 Selenium 库中的 WebDriverWait 方法来等待一个元素可见。

具体解释如下:

  • driver:驱动对象。
  • 10:表示等待的时间(单位是秒)。
  • expected_conditions.visibility_of_element_located(element):是期望的条件,即等待指定的元素可见。

这段代码的作用是在指定的时间内(10 秒)等待元素可见。如果在等待时间内元素可见,则代码继续执行;如果超过等待时间元素仍不可见,则会抛出异常。

通过使用 WebDriverWait 和期望条件,可以增加测试的稳定性和可靠性,以确保在执行后续操作之前元素处于所需的状态。

方法应用:
import time
from appium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from appium.options.android import UiAutomator2Options
from selenium.webdriver.support import expected_conditions as EC


# 定义一个获取元素的方法
def get_element_new(driver, element):
    element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located(element))
    return element


# 定义一个初始化APP的方法
def start_app(app_package, app_activity):

    # 定义desired_caps 字典,初始化app的配置信息
    desired_caps = {
          "platformName": "android",  # 表示的是android
          "platformVersion": "10",  # 表示的是设备系统的版本号
          "deviceName": "DWV6R19A10002101",  # 表示的是设备的ID名称
          "appPackage": app_package,  # 表示的是app的包名
          "appActivity": app_activity,  # 表示的是app的界面名
          "newCommandTimeout": 100000,
          "noReset": True
    }
    # 创建 Appium 驱动实例
    options = UiAutomator2Options().load_capabilities(desired_caps)
    driver = webdriver.Remote("http://localhost:4723/wd/hub", options=options)

    # 启动应用程序
    driver.wait_activity(desired_caps, 5)
    return driver


if __name__ == "__main__":
    # 本次启动的应用程序包名和活动名(作业帮)
    app_package_zyb = "com.baidu.homework"
    app_activity_zyb = ".activity.index.IndexActivity"

    # 启动应用程序
    driver_zyb = start_app(app_package_zyb, app_activity_zyb)

    # 通过元素id来进行元素定位,定位到作业批改年级选择框并点击
    element = (By.ID, 'com.baidu.homework:id/user_grade')
    grade_select = get_element_new(driver_zyb, element)
    if grade_select.is_displayed():
        grade_select.click()
        print("grade_select clicked")
    else:
        print("grade_select not found or not displayed")

    # 通过XPATH来进行元素定位,定位到六年级并点击,设置年级成功
    element = (By.XPATH, '//android.widget.TextView[@resource-id="com.baidu.homework:id/gradeName" and @text="六年级"]')
    grade_set = get_element_new(driver_zyb, element)
    if grade_set.is_displayed():
        grade_set.click()
        print("grade_set clicked")
    else:
        print("grade_set not found or not displayed")

    # 通过CLASS_NAME定位到"我的"并点击,进入我的tab页
    element = (By.CLASS_NAME, "android.widget.ImageView")
    may_tab = get_element_new(driver_zyb, element)
    if may_tab.is_displayed():
        may_tab.click()
        print("may_tab clicked")
    else:
        print("may_tab not found or not displayed")

    # 关闭浏览器
    time.sleep(3)
    print("代码执行完毕")
    driver_zyb.quit()

未完待续……

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值