【L1.第六章】Appium 如何定位与页面等待实战

devtools/2024/11/15 6:57:37/
webkit-tap-highlight-color: rgba(0, 0, 0, 0);">

Python+Appium+Pytest 自动化测试教程

  • 1、App 自动化应用控制
    • 1.1、启动
    • 1.2、关闭
  • 2、常见控件定位方法
    • 2.1、控件定位方式
    • 2.2、控件查找方法 find_elements & find_element
    • 2.3、常用定位方式
  • 3、 强制等待与隐式等待
    • 3.1、强制等待
    • 3.2、隐式等待
    • 3.3、显式等待

1、App 自动化应用控制

1.1、启动

启动应用主要有两种方式:

  1. 正常启动应用。
  2. 在脚本中启动其他应用

正常启动应用:创建一个 WebDriver 实例,用于与 Appium 服务器建立连接,并传递所需的启动配置(Desired Capabilities)。主要需要以下两个参数:

  • url:指定 Appium 服务器的 URL 地址。这通常是 Appium
    服务器的主机名和端口号,例如http://localhost:4723。

  • capability:一个字典对象,包含了启动应用程序时的配置信息。这些配置信息可以包括设备名称、平台版本、应用程序包名、活动名称、自动化测试引擎、设备连接信息等。

通过将 URL 和 Capabilities 传递给启动方法,Appium 客户端库将与 Appium 服务器建立连接,并使用提供的配置信息启动相应的会话。这将创建一个可以用于与应用程序进行交互的 WebDriver 实例。

在脚本中启动其他应用:可以在设备上激活给定的应用程序,传入的 app_id 为指定应用的包名。

python"># 启动应用:
appium_server_url = 'http://localhost:4723'
driver = webdriver.Remote(appium_server_url,options=UiAutomator2Options().load_capabilities(caps))# 在脚本中启动其他应用:
driver.activate_app("com.xx.xx")

1.2、关闭

  1. 关闭指定 app:关闭当前操作的 app,不会关闭驱动对象
  2. 关闭驱动对象:关闭当前所有的关联的 app,并关闭驱动对象
python"># 关闭指定 app
driver.terminate_app("com.xx.xx")
# 关闭当前所有的关联的 app,并关闭驱动对象
driver.quit()

2、常见控件定位方法

2.1、控件定位方式

在 Appium 中,控件定位是指通过一些标志性的特征来定位应用界面中的元素,以便进行自动化测试操作。Appium 支持多种控件定位方式,以下是一些常见的方法。

定位策略描述
Accessibility ID识别一个唯一的 UI 元素,对于 XCUITest 引擎,它对应的的属性名是 accessibility-id,对于 Android 系统的页面元素,对应的属性名是 content-desc
Class name对于 iOS 系统,它的 class 属性对应的属性值会以XCUIElementType开头,对于 Android 系统,它对应的是 UIAutomator2 的 class 属性(e.g.: android.widget.TextView)
ID原生元素的标识符,Android 系统对应的属性名为resource-id,iOS 为name
Name元素的名称
XPath使用 XPath 表达式查找页面所对应的 xml 的路径

2.2、控件查找方法 find_elements & find_element

  • 返回单个元素 WebElement
  • 返回元素列表 [WebElement, WebElement, WebElement…]
python"># 返回单个元素 WebElement
driver.find_element(AppiumBy.xxx, "xxx属性值")
# 返回元素列表 [WebElement, WebElement, WebElement...]
driver.find_elements(AppiumBy.xxx, "xxx属性值")# find_elements & find_element 一个有s

2.3、常用定位方式

ID 定位

  • 通过身份标识 id 查找元素
  • 写法:find_element(AppiumBy.ID, “ID属性值”)

ACCESSIBILITY_ID 定位

  • 通过 accessibility id 查找元素
  • 写法:find_element(AppiumBy.ACCESSIBILITY_ID, “ACCESSIBILITY_ID属性值”)

XPath 定位

  • 单属性定位://*[@属性名=‘属性值’]
  • 多属性定位://*[@属性名=‘属性值’ and @属性名=‘属性值’ ]
表达式描述
/
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置(取子孙节点)。
.选取当前节点。
选取当前节点的父节点。
@选取属性。

演示代码

python">from appium import webdriver# 设置 Desired Capabilities
desired_caps = {'platformName': 'Android','deviceName': 'My Device','appPackage': 'com.example.app','appActivity': '.MainActivity'
}# 初始化 WebDriver
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)# 通过 Accessibility ID 定位
element = driver.find_element_by_accessibility_id('someAccessibilityID')# 通过 Class Name 定位
element = driver.find_element_by_class_name('android.widget.TextView')# 通过 ID 定位
element = driver.find_element_by_id('someID')# 通过 Name 定位
element = driver.find_element_by_name('someName')# 通过 XPath 定位
element = driver.find_element_by_xpath('//android.widget.TextView[@text="Example Text"]')# 与元素交互,例如点击
element.click()# 关闭 WebDriver
driver.quit()

3、 强制等待与隐式等待

3.1、强制等待

解决方案:在报错的元素操作之前添加等待。
原理:线程休眠一定时间。

python"># 导入包
import timetime.sleep(3)  # 等待3秒

3.2、隐式等待

问题:难以确定元素加载的具体等待时间。

解决方案:针对于寻找元素的这个动作,使用隐式等待添加配置。
原理:隐式等待是一种全局的等待方式,设置一个等待时间,轮询查找(默认 0.5 秒)元素是否出现,如果没出现就抛出异常。

python">#设置一个等待时间,轮询查找(默认0.5秒)元素是否出现,如果没出现就抛出异常
driver.implicitly_wait(3)  # 等待3秒

隐式等待无法解决的问题

元素可以找到,使用点击等操作,出现报错。

原因:

  • 页面元素加载是异步加载过程,通常 xml 会先加载完成,相应的元素属性后加载。
  • 元素存在与否是由 xml 决定,元素的交互是由属性决定。
  • 隐式等待只关注元素能不能找到,不关注元素能否点击或者进行其他的交互。

解决方案:使用显式等待。

3.3、显式等待

示例: WebDriverWait(driver实例, 最长等待时间, 轮询时间).until(结束条件)。

原理:在最长等待时间内,轮询,是否满足结束条件。

python"># 导入需要的包
import time
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWaitclass TestWait:def setup_class(self):'''完成 capability 设置初始化 driver:return:'''# 设置 cpabilitycaps = {# 设置 app 安装的平台(Android,iOS)"platformName": "Android",# 设置 appium 驱动"appium:automationName": "uiautomator2",# 设置设备名称"appium:deviceName": "遥遥领先",# 设置被测 app 的包名"appium:appPackage": "com.android.system",# 设置被测 app 启动页面的 Activity"appium:appActivity": ".ApiDxxsx"}# 初始化 driverself.driver = webdriver.Remote("http://127.0.0.1:4723",options=UiAutomator2Options().load_capabilities(caps))# 设置全局隐式等待self.driver.implicitly_wait(5)def teardown_class(self):'''关闭 driver:return:'''self.driver.quit()def test_wait(self):'''点击 OS 按钮后等待 3 秒显示等待 Morse Code 元素可点击输入框输入内容后等待 2 秒点击返回按钮后等待 2 秒:return:'''# 测试步骤# 找到 OS 元素el1 = self.driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value="OS")# 点击 OS 元素el1.click()# 等待 3 秒time.sleep(3)# 显示等待 Morse Code 元素可点击el2 = WebDriverWait(self.driver, 10).until(expected_conditions.element_to_be_clickable((AppiumBy.ACCESSIBILITY_ID, "Morse Code")))# 找到 Morse Code 元素el2.click()# 等待 3 秒time.sleep(3)# 找到输入框元素el3 = self.driver.find_element(AppiumBy.ID, "io.appium.android.apis:id/text")# 在输入框中输入内容el3.send_keys("ceshiren.com")# 等待 2 秒time.sleep(2)# 点击返回按钮self.driver.back()# 等待 2 秒time.sleep(2)# 点击返回按钮self.driver.back()# 断言:判断首页中第一个元素的文本内容是 Access'ibilityresult = self.driver.find_element(AppiumBy.XPATH,"//*[@resource-id='android:id/text1'][1]")print(result.text)assert result.text == "Access'ibility"

http://www.ppmy.cn/devtools/114926.html

相关文章

我Github的问题解决了!

看的这篇,解决使用git时遇到Failed to connect to github.com port 443 after 21090 ms: Couldn‘t connect to server_git couldnt connect to server-CSDN博客 之前想推送的能推送了,拉取的也能取了。 一、如果是在挂着梯子的情况下拉取或者推送代码…

北银金科:北京银行“金融操作系统”建设项目

在数字经济的背景下,金融服务体系以数据为关键生产要素、以科技为核心生产工具、以平台生产为主要生产方式,需要一个类似于计算机操作系统的金融操作系统,向下对接大量设备、海量数据,向上支撑金融数字化转型的快速开发与部署,实现数据的可信共享、资源的合理配置、服务的…

黑神话悟空mac可以玩吗

黑神话悟空mac上能不能玩对于苹果玩家来说很重要,那么黑神话悟空mac可以玩吗?目前是玩不了了,没有针对ios系统的版本,只能之后在云平台上找找了,大家可以再观望下看看。 黑神话悟空mac可以玩吗 ‌使用CrossOver‌&…

Vue.js props 子组件可以从父组件接收数据(通过 props)并可以向父组件发送事件(通过 $emit)

父子组件之间可以通过事件和 props 进行通信,但通常是单向的:父组件向子组件传递数据(props),子组件向父组件发送事件($emit)。 方式 父组件传递数据给子组件: 使用 props。 子组件通知父组件…

Python | Leetcode Python题解之第412题Fizz Buzz

题目: 题解: class Solution:def fizzBuzz(self, n: int) -> List[str]:ans []for i in range(1, n 1):s ""if i % 3 0:s "Fizz"if i % 5 0:s "Buzz"if s "":s str(i)ans.append(s)return ans

SSMP+ajax实现广告系统的分页效果

文章目录 1.案例需求2.编程思路3.案例源码4.小结 1.案例需求 使用SSMPajax实现广告系统的分页效果,效果图如下: 2.编程思路 mapper层:定义一个接口,继承自BaseMapper,指定泛型为AdvInfo,这样MyBatis Pl…

Maven版本号管理

背景 A,B项目依赖C项目,开发时候C项目使用快照版本,发布前修改为正式版本号,但是每次都需要ABC项目修改代码,有没有不修改代码的实现方式? 方案1: 打包时动态修改 可以使用 Maven 的 Profiles 和 Proper…

Python数据分析案例60——扩展变量后的神经网络风速预测(tsfresh)

案例背景 时间序列的预测一直是经久不衰的实际应用和学术研究的对象,但是绝大多数的时间序列可能就没有太多的其他的变量,例如一个股票的股价,还有一个企业的用电量,人的血糖浓度等等,空气的质量,温度这些…