app测试 - 元素定位

542 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第25天,点击查看活动详

在命令行中直接输入uiautomatorviewer即可打开,但是命令较长,可以将该文件(\android-sdk\tools下)复制一份,然后改一个简单的名字(uiauto)即可。

该工具automator可以帮助查找app上的元素信息。

打开app之后就可以将页面加载到工具中,然后可以看到元素信息.

需要注意的是在代码对app进行操作时,automator工具会和代码产生冲突,无法获取元素信息,解决方式是,可以将页面信息先保存起来。一个界面会保存两个文件,一个是图片,一个是元素文件。这样在编写代码时,可以直接通过本地文件而无需占用app来查找元素信息。即先保存界面再写代码。

当代码和automator工具之间产生错误之后,automator会报错,此时需要重新启动adb服务。

app元素定位

  • 通过ID定位元素

通过元素的source-id来定位。但是多个元素的ID可能相同

from appium.webdriver.common.appiumby import AppiumBy, By  # 只有最新版本的`Appium-Python-Client`才支持该方法
from selenium.webdriver.common.by import By
# 两种方式都可以
driver.find_element(by=AppiumBy.ID, value='resource-id')
driver.find_element(by=By.ID, value='resource-id')  # 更通用
  • 通过class_name定位元素

通过元素的class属性值进行元素定位,多个元素的值可能也想通

需要注意的是在app中class的值只有一个

# 两种方式都可以
driver.find_element(by=AppiumBy.CLASS_NAME, value='class_value')
driver.find_element(by=By.CLASS_NAME, value='class_value')  # 更通用
  • 通过xpath定位元素

通过元素的xpath进行定位,在app中xpath使用的是元素的text的值。

# 两种方式都可以
driver.find_element(by=AppiumBy.XPATH, value='//*[@text=text_value]')
driver.find_element(by=By.XPATH, value='//*[@text="text_value"]')  # 更通用
  • 三种元素定位结合小案例
import time

from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy, By

# 初始化app的配置信息,是一个字典
des_cap = {
    "platformName": "android",  # 操作系统
    "platformVersion": "5.1.1",  # 操作系统版本
    "deviceName": "****",  # 如果只连接一个设备,可以使用****代替,如果有多个设备需要写设备ID
    "appPackage": "com.android.settings",  # app的包名
    "appActivity": ".Settings"  # 表示app的界面名
}

# 通过初始化操作打开一个应用(设置):参数说明:command_executor:appium服务(有默认值参考源代码)  desired_capabilities:app配置信息
driver = webdriver.Remote(command_executor='http://127.0.0.1:4444/wd/hub', desired_capabilities=des_cap)
# 点击更多
more_ele = driver.find_element(by=AppiumBy.XPATH, value='//*[@text="更多"]')
more_ele.click()
time.sleep(2)
# 打开飞行模式
fly_ele = driver.find_element(by=By.ID, value='android:id/switchWidget')
fly_ele.click()
time.sleep(2)
# 点击返回按钮
back_ele = driver.find_element(by=AppiumBy.CLASS_NAME, value='android.widget.ImageButton')
back_ele.click()
time.sleep(4)

driver.quit()  # 退出
元素等待 - 参考web的元素等待

通常使用的是显式等待。

from selenium.webdriver.support.wait import WebDriverWait


def get_element(driver, ele_info: dict[str: typing.Any]):
    element = WebDriverWait(driver=driver, timeout=5, poll_frequency=1).until(lambda x: x.find_element(**ele_info))
    return element

---------------------------------------------------------------------------------------
from appium.webdriver.common.appiumby import AppiumBy, By

driver = webdriver.Remote(command_executor='http://127.0.0.1:4444/wd/hub', desired_capabilities=des_cap)
ele_info ={
    "by": By.ID,
    "value": 'android:id/switchWidget'
}'
ele = get_element(driver, ele_info)
定位一组元素

可以通过id class_name xpath进行一组元素的定位,如果没有定位到元素会返回一个空列表。

driver.find_elements(by=By.ID, value='id_value')