坚持原创输出,点击蓝字关注我吧

作者:清菡

博客:oschina、云+社区、知乎等各大平台都有。

目录

  • 一、滑屏操作

    • 1.访问之后,马上就滑屏可以吗?
    • 2.连续实现 2 次滑屏
    • 3.代码
  • 二、模拟触屏
    • 1.短按和点击的区别?
    • 2.用坐标还是元素?
    • 3.引入 TouchAction
    • 4.每个行为函数都有 3 个参数
    • 5.首先确定每一个点的位置
    • 6.代码
  • 三、注意

一、滑屏操作

不需要看到欢迎页面,直接做里面的后续操作就好了。也就是我想记住一些用户的习惯, 不要像第一次访问一样,有一个重置与否,给它关闭了。

# 重置与否
desired_caps["noReset"]=True

1.访问之后,马上就滑屏可以吗?

不可以。先等待首页有个元素出现,再去滑屏。滑屏操作需要时间,模拟器或者真机执行操作更需要时间。如果直接滑动 2 次,第一次滑动效果还没展示出来就直接滑动第二次了,就会看到看不懂得现象。所以这种情况下就要加上time

2.连续实现 2 次滑屏

#从右向左滑
driver.swipe(start_x,start_y,end_x,end_y,200)
time.sleep(1)
driver.swipe(start_x,start_y,end_x,end_y,200)

3.代码

# 微信app 安卓
from appium import webdriver
import time
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from appium.webdriver.common.mobileby import MobileBy desired_caps={}
# 平台类型
desired_caps["platformName"]="Android"
# 平台版本号
desired_caps["platformVersion"]="7.0"
# 设备名称
desired_caps["deviceName"]="XPUDU17713003790"
# app 包名
desired_caps["appPackage"]="com.tencent.mm"
# app 入口 acitivity
desired_caps["appActivity"]="com.tencent.mm.ui.LauncherUI"
# 重置与否
desired_caps["noReset"]=True # aapt dump badging 包名
# 连接Appium server。前提:appium desktop要启动。有监听端口。
# 将desired_caps发送给appium server。打开app
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_caps) # ANDROID_UIAUTOMATOR 这个是一种定位表达式,用其它的表达式也是可以的。
loc=(MobileBy.ANDROID_UIAUTOMATOR,'new UiSelector().text("通讯录")')
WebDriverWait(driver,30).until(EC.visibility_of_element_located(loc)) #height、width
size= driver.get_window_size()
start_x=size['width']*0.9
start_y=size['height']*0.5 end_x=size["width"]*0.1
end_y=size['height']*0.5 #从右向左滑
# 时间长短需要根据实际情况自己来调试,避免没滑过去,代码就执行完毕了。
driver.swipe(start_x,start_y,end_x,end_y,300)
time.sleep(2)
driver.swipe(start_x,start_y,end_x,end_y,300)

二、模拟触屏

滑屏也是触屏实现的。手指在屏幕上点点点,在 Appium 中提供了专门的TouchAction类来做这件事。

Press、longPressrelease组合起来使用的。长按和短按的时间长度不同。

move_to手按住别松开,一直滑动到另外一个点。在每一个操作之间都调用下wait,暂缓下它们的操作间隙,不然太快了,看起来就是一团乱麻。

1.短按和点击的区别?

短按是按住不松开,但是时间比较短。tap是点完就松开,不需要组合别的一起用。有Press就必须有release,不然就一直按着上面动都不动了。

发送命令后,只有调用perform才能真的去执行些操作命令,否则是不行的。

将所有的行为按要求放在列表中,可以将列表中所有的东西取消cancel

滑屏操作是在屏幕上按住一个点,然后滑动到另外一个点,最后把它松掉。

九宫格就是个典型的触屏应用。

2.用坐标还是元素?

元素方便简单,但是不是你想选就一定是哪一种。一种情况,9 个点都是独立的元素,那么用元素就可以了;第二种情况,9 个点都在一个元素里面怎么办?就没有办法实现元素的移动,因为就一个元素。这个时候就必须要用坐标。

坐标需要精确定位。需要思考每个坐标之间的关系。

3.引入 TouchAction

from appium.webdriver.common.touch_action import TouchAction

TouchAction 的源码:

4.每个行为函数都有 3 个参数

swipe滑屏操作是没有元素的,针对的是整个屏幕。屏幕的话就只能通过坐标点。所以你看swipe的源码就可以看到。

看下 swipe 的实现-源码:

  action = TouchAction(self) #首先实例化TouchAction
action \
.press(x=start_x, y=start_y) \
.wait(ms=duration) \
.move_to(x=end_x, y=end_y) \
.release()
action.perform()
return self

现在是它帮你封装好了。实际上不用swipe,就用TouchAction自己去写都可以。

x=end_x, y=end_y,没有用el。

5.首先确定每一个点的位置

选择一个元素上的坐标,大概会选哪个位置的?

中心。

坐标轴写错了一点,偏移了点,好歹也是在范围之内。如果选择边缘的点,偏了点可能就出不去了。所以,一般选一个元素的坐标,尽量选择中心。 每个点之间的间隔是一样的。从一个点挪到另外一个点,y 轴不用动,x 轴只要有个固定的距离就好了。

例如 3 个点的值是:147.376、359.378、571.378

能把这 3 个值直接这样写出来吗?

不能。换台设备就不行了,这样绝对的数据是不能放在这里的。采用和滑屏操作一样的思想,用百分比和相对距离。如果能获取到元素的大小以及起点坐标就可以了。

距离是 59。147-59=88

可以估算一下:

如果是长方形那就需要另外再算,但是图中是正方形,这 9 个格子的间距是没有什么区别的,重点是它与边界值的差距。

边界值的差距是多少?

把它分成 6 份。第一个点的坐标:能够得到 view 的起点坐标是 45,272。有专门的函数可以获取元素的大小以及它的起点坐标。

假设起点坐标是 x、y,我现在已经知道将它分成了 6 份。

那么,第一个点的坐标怎么写?

x+width*1/6 + height*1/6

看 size 源码:

看 location 源码:

#元素的大小
size=ele.size
# 均分的步长 高和宽一样(因为是正方形)
step=size["width"]/6#py3中除是取整数的,会缺点小数点没关系。取得是终点,问题不大,还是可以滑动到的。
# 元素的起点坐标-左上角
ori=ele.location
point1=(ori["x"]+step,ori["y"]+step)
TouchAction(driver)

等于横向走了这么远,纵向也走了这么远,刚好对着这个点了。

第二个点的坐标怎么算?

基于第一个点的基础上做调整就行了。y 轴不变,x 轴往前走了 2 份。

第3个点也是在第2个点的基础上往前挪动了2个。

#元素的大小
size=ele.size
# 均分的步长 高和宽一样(因为是正方形)
step=size["width"]/6#py3中除是取整数的,会缺点小数点没关系。取得是终点,问题不大,还是可以滑动到的。
# 元素的起点坐标-左上角
ori=ele.location
point1=(ori["x"]+step,ori["y"]+step)
point2=(point1[0]+step*2,point1[1]) #x轴增加了2*step
point3=(point2[0]+step*2,point2[1]) #x轴增加了2*step
TouchAction(driver)

第4个点的坐标:

它是倒着往回走。

第5个点的坐标。

#元素的大小
size=ele.size
# 均分的步长 高和宽一样(因为是正方形)
step=size["width"]/6#py3中除是取整数的,会缺点小数点没关系。取得是终点,问题不大,还是可以滑动到的。
# 元素的起点坐标-左上角
ori=ele.location
point1=(ori["x"]+step,ori["y"]+step)
point2=(point1[0]+step*2,point1[1]) #相对于point1,x轴增加了2*step
point3=(point2[0]+step*2,point2[1]) #相对于point2,x轴增加了2*step
point4=(point3[0]-step*2,point3[1]+step*2)#相对于point3,x轴减少了2*step,y轴增加了2*step
point5=(point4[0],point4[1]+step*2)#相对于point4,x轴不变,y轴增加了2*step
TouchAction(driver).press(x=point1[0],y=point1[1]).wait(200).\
move_to(x=point2[0],y=point2[1]).wait(200).\
move_to(x=point3[0],y=point3[1]).wait(200).\
move_to(x=point4[0],y=point4[1]).wait(200).\
move_to(x=point5[0],y=point5[1]).wait(200).\
release().\
perform() #.\是换行用的。

以 1 个点做基准,针对不同的点做基准,容易把自己绕晕了。所以,都以前一个点做基准。也可以以起点作为基准。

6.代码


from appium import webdriver
import time
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from appium.webdriver.common.mobileby import MobileBy
import time
from appium.webdriver.common.touch_action import TouchAction desired_caps={}
# 平台类型
desired_caps["platformName"]="Android"
# 平台版本号
desired_caps["platformVersion"]="7.0"
# 设备名称
desired_caps["deviceName"]="XPUDU17713003790"
# app 包名
desired_caps["appPackage"]="填上appPackage"
# app 入口 acitivity
desired_caps["appActivity"]="填上appActivity"
# 重置与否
desired_caps["noReset"]=True # 连接Appium server。前提:appium desktop要启动。有监听端口。
# 将desired_caps发送给appium server。打开app
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_caps) ele=driver.find_element_by_id("填上元素定位下吧,如果你app这里的元素定位不了,那就只能用坐标了,需要另外学习这块的坐标怎么写,呜呜")
# 元素的大小
size=ele.size
# 均分的步长 高和宽一样(因为是正方形)
step=size["width"]/6#py3中除是取整数的,会缺点小数点没关系。取得是终点,问题不大,还是可以滑动到的。 # 元素的起点坐标-左上角
ori=ele.location
point1=(ori["x"]+step,ori["y"]+step)
point2=(point1[0]+step*2,point1[1]) #相对于point1,x轴增加了2*step
point3=(point2[0]+step*2,point2[1]) #相对于point2,x轴增加了2*step
point4=(point3[0]-step*2,point3[1]+step*2)#相对于point3,x轴减少了2*step,y轴增加了2*step
point5=(point4[0],point4[1]+step*2)#相对于point4,x轴不变,y轴增加了2*step
TouchAction(driver).press(x=point1[0],y=point1[1]).wait(100).\
move_to(x=point2[0],y=point2[1]).wait(100).\
move_to(x=point3[0],y=point3[1]).wait(100).\
move_to(x=point4[0],y=point4[1]).wait(100).\
move_to(x=point5[0],y=point5[1]).wait(100).\
release().\
perform() #.\是换行用的。

三、注意

这里是 V1.6.几的或 V1.7.1,V1.7 以前的,如果按上面代码的方式写坐标的话,会报错“提示越界了”这个是版本差异引起的。 需要看日志,日志中会告诉你,当前滑动的点是什么。

多看Appium中的日志,它会问你是el滑动还是坐标滑动?

坐标滑动会直接打印坐标值,看下坐标值超了就说明是有问题的。版本比较晚的应该都是绝对坐标。

实际上是不会“越界”的,那只因为用的相对距离来滑动的。move_to的每一个坐标点都是真实的绝对坐标。

用的当前元素的原坐标点加上移动的距离得到的是当前相对于整个屏幕左上角这个 00 的真实坐标值。

我现在用的坐标,但是有的版本的问题是:

它的move_to参数不是绝对坐标。而是相对于上一个点的移动距离。

比如第一个点,press 是没有错的。用 move_to 的时候 y 没有动,x 轴移动了 2 倍 step。

如果是这种相对距离移动的话,要求x=2*step,没有坐标,y=0。如果不是按这种风格写的,会报“越界”

它拿着上一个点的坐标值加上 x,y,得出来肯定超界了。因为代码里写的真实坐标,再加上 x,第二个点可能没有越界,第三个点就越界了。

如果报“越界”错误,那么就改成相对坐标滑动一下,看看有没有报错。

Appium 在不同的版本修复了不同的问题,但是修复的同时也可能出现不同的问题。


公众号清菡软件测试首发,更多原创文章:清菡软件测试 94+原创文章,欢迎关注、交流,禁止第三方擅自转载。

Appium常用操作之「微信滑屏、触屏操作」的更多相关文章

  1. 「微信小程序免费辅导教程」26,基础内容组件rich-text体验

  2. 「微信小程序免费辅导教程」25,基本内容组件text的使用及个人帐号允许的服务类目

  3. 「微信小程序免费辅导教程」24,基础内容组件icon的使用探索与7月26日微信公众平台的更新解读

  4. WPF技术触屏上的应用系列(五): 图片列表异步加载、手指进行缩小、放大、拖动 、惯性滑入滑出等效果

    原文:WPF技术触屏上的应用系列(五): 图片列表异步加载.手指进行缩小.放大.拖动 .惯性滑入滑出等效果 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系统, ...

  5. WPF技术触屏上的应用系列(六): 视觉冲击、超炫系统主界面、系统入口效果实现

    原文:WPF技术触屏上的应用系列(六): 视觉冲击.超炫系统主界面.系统入口效果实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系统,54寸大屏电脑电视一体 ...

  6. WPF技术触屏上的应用系列(四): 3D效果图片播放器(图片立体轮放、图片立体轮播、图片倒影立体滚动)效果实现

    原文:WPF技术触屏上的应用系列(四): 3D效果图片播放器(图片立体轮放.图片立体轮播.图片倒影立体滚动)效果实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7 ...

  7. WPF技术触屏上的应用系列(三): 视频播放器的使用及视频播放、播放、暂停、可拖动播放进度效果实现

    原文:WPF技术触屏上的应用系列(三): 视频播放器的使用及视频播放.播放.暂停.可拖动播放进度效果实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系统,5 ...

  8. WPF技术触屏上的应用系列(一): 3D 图片(照片)墙、柱面墙(凹面墙或者叫远景墙、凸面墙或者叫近景墙)实现

    原文:WPF技术触屏上的应用系列(一): 3D 图片(照片)墙.柱面墙(凹面墙或者叫远景墙.凸面墙或者叫近景墙)实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7 ...

  9. WPF技术触屏上的应用系列(二): 嵌入百度地图、API调用及结合本地数据库在地图上进行自定义标点的实现

    原文:WPF技术触屏上的应用系列(二): 嵌入百度地图.API调用及结合本地数据库在地图上进行自定义标点的实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系 ...

随机推荐

  1. Oracle12c 使用总结

    /*创建临时表空间 */create temporary tablespace BBB tempfile 'D:\APP\oracle\oradata\orcl\BBB.dbf' size 500m ...

  2. 基于Scrapy的交互式漫画爬虫

    Github项目地址 前言 该项目始于个人兴趣,本意为给无代码经验的朋友做到能开箱即用 阅读此文需要少量Scrapy,PyQt 知识,全文仅分享交流 摘要思路,如需可阅读源码,欢迎提 issue 一. ...

  3. 04 Storage and Calculation C语言中的存储和计算

    文章内容来源于Programming Hub的学习记录,本人整理添加了中文翻译,如有侵权,联系本人删除 Variables C语言中的变量 Let's extend our mainfunction ...

  4. C\C++中计时、延时函数

    转载:https://blog.csdn.net/keith_bb/article/details/53055380 C\C++标准库中提供了两种计时函数clock()和time().其用法如下:(1 ...

  5. IDEA2020.2的破解

    第一种方式:http://code.39sd.cn/ 直接获取二维码: 第二种:下载破解工具(本方法只是提供个人学习使用) 1.下载2020.2的idea 链接:https://pan.baidu.c ...

  6. 最全vue的vue-amap使用高德地图插件画多边形范围

    一.在vue-cli的框架下的main.js(或者main.ts)中引入高德插件,代码如下: import Vue from 'vue' import VueAMap from 'vue-amap' ...

  7. Oracle 正确删除归档日志的方法

    我们都知道在controlfile中记录着每一个archivelog文件的相关信息,当然们在OS下把这些物理文件delete掉后,在我们的controlfile中仍然记录着这些archivelog文件 ...

  8. rxjs入门5之创建数据流

    一 创建同步数据流 1.creat Observable.create = function (subscribe) { return new Observable(subscribe); }; 2. ...

  9. 使用git 版本控制的代码在线修调试,如何还原

    在线调试: 先切换成www用户进入项目的根目录比如/data/wwwroot/website su www cd /data/wwwroot/website vi ./api/controllers/ ...

  10. 测试AAA

    程序计数器(线程私有) 程序计数器(Program Counter Register),也有称作为 PC 寄存器.保存的是程序当 前执行的指令的地址(也可以说保存下一条指令的所在存储单元的地址),当 ...