https://blog.csdn.net/weixin_45912307/article/details/122464199
appium官网:https://appium.io/
注:appium原理可参考此篇https://www.sohu.com/a/447193582_371153
官网:https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md
{
"platformName": "Android", # 平台名称:ios、Android
"platformVersion": "5.1.1", # 平台版本
"deviceName": "emulator-5554", # 设备名称,可不填
"appPackage": "com.hundsun.winner.pazq", # 包名
"appActivity": "com.hundsun.winner.pazqapp.ui.home.activity.NewSplashActivity", # 启动入口页面
"noRest": False, # 是否在测试前后重置相关环境,默认False
"skipServerInstallation": True # 跳过安装、权限设置等 *** 作
# "skipDeviceInitialization":True
# "unicodeKeyboard": True # 输入中文时设置为True,默认False
# "resetKeyboard":True 是否重置输入法,默认False
# "dontStopAppOnReset": Ture # 首次启动的时候,不停止app ,默认为false
}
3.2 三种等待方式
隐式等待:默认都加上,一般设置3-6s显示等待:文件上传需要设置20s以上强制等待:尽量少用,影响耗时性能
3.2.1强制等待:
time.sleep() 不推荐
3.2.2 全局隐式等待(在服务端等待)driver.implicitly_wait(TIMEOUT)
3.2.3显式等待(在客户端等待)WebDriverWait(driver,15,0.5).until(expected_conditions.visibility_of_element_located((MobileBy.定位方式,‘id/名称/属性值’)))
1. 使用说明 显示等待与隐式等待相对,显示等待必须在每个需要等待的元素前面进行声明。是针对于某个特定的元素设置的等待时间,在设置时间内,默认每隔一段时间检测一次当前页面某个元素是否存在,如果在规定的时间内找到了元素,则直接执行,即找到元素就执行相关 *** 作,如果超过设置时间检测不到则抛出异常。默认检测频率为0.5s,默认抛出异常为:NoSuchElementException用到的两个类:WebDriverWait
和expected_conditions
两个类
2. WebDriverWait用法
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
driver
:浏览器驱动timeout
:最长超时时间,默认以秒为单位 poll_frequency:检测的间隔步长,默认为0.5signored_exceptions
:超时后的抛出的异常信息,默认抛出NoSuchElementExeception
异常。
3. WebDriverWait的until()
和until_not()
方法:
method
:在等待期间,每隔一段时间(_init_中的poll_frequency)调用这个传入的方法,直到返回值不是Falsemessage
:如果超时,抛出TimeoutException
,将message传入异常until_not
: 与until相反,until是当某元素出现或什么条件成立则继续执行,until_not是当某元素消失或什么条件不成立则继续执行,参数也相同。
3.3 android、ios基础知识
3.3.1 android
Android是通过容器的布局属性来管理子控件的位置关系,布局过程就是把界面上的所有的控件根据他们的间距的大小,摆放在正确的位置
Android七大布局
LinearLayout
(线性布局)RelativeLayout
(相对布局)FrameLayout
(帧布局)AbsoluteLayout
(绝对布局)TableLayout
(表格布局)GridLayout
(网格布局)ConstraintLayout
(约束布局) Android四大组件
activity
:与用户交互的可视化界面service
:实现程序后台运行的解决方案content provider
:内容提供者﹐提供程序所需要的数据broadcast receiver
:广播接收器,监听外部事件的到来(比如来电) 常用的控件:
TextView
(文本控件)EditText
(可编辑文本控件)Button
(按钮)ImageButton
(图片按钮)ToggleButton
(开关按钮)ImageView
(图片控件)CheckBox
(复选框控件)RadioButton
(单选框控件)
3.3.2 ios
布局: iOS去掉了布局的概念、直接用变量之间的相对关系完成位置的计算
3.4 app元素定位方式
1. id定位(首选)
写法1:driver.find_element_by_id(resource-id属性值)
写法2:driver.find_element(MobileBy.ID,"resource:id")
写法3:
from appium.webdriver.common.mobileby import MobileBy
loc = (MobileBy.ID,'resource-id属性值')
driver.find_element(*loc)
2. accessibility_id定位(其次)
写法1:driver.find..element_by..accessibility..id(content-desc属性值)
写法2:driver.find_element(MobileBy.ACCESSIBILITY_ID,"content_desc:属性")
写法1:driver.find_element(MobileBy.XPATH,'xpath属性')
写法2:driver.find_element_by_xpath('xpath属性')
xpath语法:
- 绝对路径:/html/body/div[1]/div[1]/div[5]/div/div/form/span[2]/input
- 相对路径:靠元素本身特征定位
1. 以//开头
- //标签名[@属性=值] //i[@]
2. 层级定位: //一级元素//二级元素//...
//div[@id="number-attend"]//i[@]
3. 文本匹配 //标签名[text()=值] //a[text()="公告"]
4. 包含 //标签名[contains(@属性/text(),"值")]
//a[contains(@href,"/Notify/index/courseid/")]
//a[contains(text(),"公告")]
5. 逻辑运算 ,来组合更多的元素特征 and or
//标签名[@属性=值 and @属性=值 and contain(@属性/text(),值) and text()=值}]
//标签名[@属性=值 or @属性=值]
//a[text()="公告" and contains(@href,/Notify/index/courseid/")]
6. 轴定位, 关系 ---分析
- 1)通过兄弟节点找到自己
- 2)通过后代元素来到 祖先元素
ancestor:祖父结点 包括父
parent:父节点
preceding:当前元素节点标签之前的所有结点。(html页面先后顺序)
preceding-sibling:当前元素节点标签之前的所有兄弟节点
following:当前元素节点标签之后的所有结点。 (html页面先后顺序)
following-sibling:当前元素节点标签之后的所有兄弟结点
适用语法:
已知的元素/轴名称:标签名称[@属性=值]
//div//table/td/preceding::td
7. 小标/js
4. UiSelector 定位
new UiSelector().方法名称(值).方法名称(值).方法名称(值)
如:
from appium.webdriver.common.mobileby import MobileBy
loc = (MobileBy.ANDROID_UIAUTOMATOR,'new UiSelector().text("Python自动化")')
driver.find_element(*loc).click()
5. 坐标定位
os.system('adb shell tap x y')
写法1: driver.find_element_by_class_name('类名称')
写法2: driver.find_element(MobileBy.CLASS_NAME,'类名称')
from appium import webdriver
driver = webdriver.Remote(“主机:端口/wd/hub”,启动参数)
1.点击
driver.find_element(MobileBy.定位方式,'属性/id值').click()
2.键盘输入:
driver.find_element(MobileBy.定位方式,'属性/id值').send_keys()
3.设置属性值:
driver.find_element(MobileBy.定位方式,'属性/id值').set_value('属性值')
4.获取属性值:
driver.find_element(MobileBy.定位方式,'属性/id值').get_attribute()
5.清除:
driver.find_element(MobileBy.定位方式,'属性/id值').clear()
6.是否可见:
driver.find_element(MobileBy.定位方式,'属性/id值').is_displayed()
7.是否可用:
driver.find_element(MobileBy.定位方式,'属性/id值').is_enabled()
8.是否可选择:
driver.find_element(MobileBy.定位方式,'属性/id值').is_selected()
3.5.2 元素的常用属性
1.获取元素文本:
driver.find_element().text()
2.获取元素坐标:
driver.find_element().location()
3.获取元素尺寸(高和宽):
driver.find_element().size()
官网:https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/touch-actions.md
3.6.1 滑屏 *** 作 从一个坐标位置滑动到另⼀个坐标位置,是两个点之间的滑动.方法:swipe(start_x, start_y, end_x, end_y, duration=None)
Start_x:起始的x坐标Start_y:开始的y坐标End_x:要停止的x坐标End_y:要停止的y坐标duration 滑动持续时间
3.6.2 列表滑动 *** 作(滑动屏幕底部)
"""
old=none
new=driver.page_source
while 滑动以前的内容 != 滑动以后的内容:
如果元素找着了(driver.find_element()/page_source.find()):
break
如果没找着:
滑动 *** 作
time.sleep(3)
old = new
new = driver.page_source
"""
# 获取屏幕大小
size = driver.get_window_size()
old=None
new=driver.page_source
while old != new:
try:
driver.find_element_by_android_uiautomator('new UiSelector().text("底部元素文本值")')
except:
driver.swipe(size['width']*0.5,size['height']*0.9,size['width']*0.5,size['height']*0.1,200)
time.sleep(3)
old = new
new = driver.page_source
else:
logging.info('找到底部元素文本值')
break
3.6.3 单点/多点触摸 *** 作
1.单点触摸(触屏)
模拟用户按下一个元素,将手指滑动到另一个位置,然后将手指从屏幕上移开方法:TouchAction().press(el0).moveTo(el1).release()
ta = TouchAction() # 实例化TouchAction类
size = driver.get_window_rect()
x = size['width']
start_y = size['height'] * 0.9
end_y = size['height'] * 0.1
ta.press(x,start_y).wait(100).move_to(x,end_y).release().perform()
2. 多点触摸(放大、缩小 *** 作)
使用说明
MultiTouch 手势只有两种方法add和perform。add 用于向此 MultiTouch 添加另一个 TouchAction。当perform被调用时,所有添加到 MultiTouch 中的 TouchAction 都会被发送到appium 并执行,就好像多个手指同时 *** 作一样。Appium 首先一起执行所有 TouchAction 的第一个事件,然后是第二个,依此类推。语法
action0 = TouchAction().tap(el)
action1 = TouchAction().tap(el)
MultiAction().add(action0).add(action1).perform()
放大 *** 作
# 1)获取屏幕尺寸
size = driver.get_window_size()
# 2)放大: 挤压 ---等待 --- 移动 --- 释放
ta = TouchAction()
a = ta.press(x=size['width']*0.5,y=size['height']*0.5).wait(100)\
.move_to(x=size['width']*0.1,y=size['height']*0.9).release()
b = ta.press(x=size['width']*0.5,y=size['height']*0.5).wait(100)\
.move_to(x=size['width']*0.9,y=size['height']*0.1).release()
ma = MultiAction(driver)
ma.add(a,b)
ma.perform()
缩小 *** 作
# 1)获取屏幕尺寸
size = driver.get_window_size()
a = ta.press(x=size['width']*0.1,y=size['height']*0.9).wait(100)\
.move_to(x=size['width']*0.5,y=size['height']*0.5).release()
b = ta.press(x=size['width']*0.9,y=size['height']*0.1).wait(100)\
.move_to(x=size['width']*0.5,y=size['height']*0.5).release()
ma = MultiAction(driver)
ma.add(a,b)
ma.perform()
3.6.4 toast处理
只能用元素存在,不能用元素可见
方式1:driver.find_element(MobileBy.XPATH, "//*[@class='class名称']").text()
方式2:driver.find_element(MobileBy.XPATH, "//*[contains(@text,'文本值')]").text()
方式3:loc = loc = (MobileBy.XPATH, '//*[contains(@text,"文本值")]')
WebDriverWait(driver, 5, 0.01).until(expected_conditions.presence_of_element_located(loc))
text = driver.find_element(*loc).text
print(text)
3.6.5 top *** 作
用最多五根手指轻敲一个特定的地方,保持一段时间
语法:tap(positions, duration)
position:表示的x/y坐标的元组数组,最大长度5点击的时长,单位毫秒 用法:driver.tap([(100, 20)], 500)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)