Appium+python自动化(二十八)- 高级滑动(超详解)

高级溜冰的滑动

滑动操作一般是两点之间的滑动,这种滑动在这里称其为低级的溜冰滑动;就是上一节给小伙伴们分享的。然而实际使用过程中用户可能要进行一些多点连续滑动操作。如九宫格滑动操作,连续拖动图片移动等场景。那么这种高级绚丽的溜冰滑动在Appium中该如何模拟这类操作呢?下面给你慢慢道来。

TouchAction

首先看一下官方文档

地址:https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.touch_actions.html

Touch Action包含一些列操作,比如按压、长按、点击、移动、暂停。由着些不同操作可以组成一套动作。使用TochAction需要先导入对应的模块

from appium.webdriver.common.touch_action import TouchAction

按压

方法:press() 开始按压一个元素或坐标点(x,y)。通过手指按压手机屏幕的某个位置。 press也可以接收屏幕的坐标(x,y)。

press(self, el=None, x=None, y=None)TouchAction(driver).press(x=0,y=308)

长按

方法:longPress() 开始按压一个元素或坐标点(x,y)。 相比press()方法,longPress()多了一个入参,既然长按,得有按的时间吧。duration以毫秒为单位。1000表示按一秒钟。其用法与press()方法相同。

long_press(self, el=None, x=None, y=None, duration=1000)

点击

方法:tap() 对一个元素或控件执行点击操作。用法参考press()。

tap(self, element=None, x=None, y=None, count=1)

移动

方法:move_to() 将指针从上一个点移动到指定的元素或点。

move_to(self, el=None, x=None, y=None)

注意:

移动到目位置有时是算绝对坐标点,有时是基于前面一个坐标点的偏移量,这个要结合具体App来实践。

暂停

方法:Wait()

wait(self, ms=0)

暂停脚本的执行,单位为毫秒。

释放

方法:release() 结束的行动取消屏幕上的指针。

release(self)

执行

方法:perform() 执行的操作发送到服务器的命令操作。

perform(self)

TouchAction实战——九宫格滑动操作

九宫格是一种比较常见的图案加密方式,目前很多App都支持设置图案锁,Android原生系统也支持设九宫格图案锁屏。那么我们该如何使用Appium进行滑动操作呢?

测试场景

安装启动随手记App 启动App后在密码设置选项中开启手机密码并滑动九宫格设置如下“Z”字形的图形密码。

测试环境

1.我的系统环境是Windows 10版本 64位系统

2.dk版本:"1.8.0_181"

3.appium版本:1.4.16

4.selenium:3.141.0

安装selenium:

输入指令pip install selenium

验证安装成功:pip show selenium

5.测试设备:Android 5.1.1 (不能低于5.0版本)

6.Python:3.7.2

命令:python -V  ,回车即可。

7.测试App:随手记Android app V9.7.1.5

想法与思路

  • 安装启动随手记APP
  • 代码实现点击“下一步”,向左滑动首页引导页面
  • 点击“开始随手记”进入首页页面
  • 点击“设置”按钮,向上滑动,找到“高级”按钮,点击进入
  • 点击“手势密码”,开始设置手势密码(高级滑动)

代码实现

(1)安装启动随手记

(2)代码实现点击“下一步”,向左滑动首页引导页面

(3)点击“开始随手记”进入首页页面

(4)点击“设置”按钮,向上滑动,找到“高级”按钮,点击进入

(5)点击“手势密码”,开始设置手势密码,进行解锁(高级滑动)

这个地方move_to到了按下的这个坐标点,是因为不这样的话实际结果忽略掉了第一个按下的点。release()释放,perform()执行。

代码运行结果

运行过程appium和夜神模拟器

参考代码

 1 # coding=utf-82 # 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行3 4 # 2.注释:包括记录创建时间,创建人,项目名称。5 '''6 Created on 2019-8-077 @author: 潇潇说测试8 Project:学习和使用appium自动化测试-高级滑动9 '''
10 # 3.导入模块
11 from appium import webdriver
12 from appium.webdriver.common.touch_action import TouchAction
13 from selenium.webdriver.support.ui import WebDriverWait
14 from selenium.common.exceptions import NoSuchElementException
15 from time import sleep
16 
17 desired_caps={}
18 desired_caps['platformName']='Android'
19 desired_caps['deviceName']='127.0.0.1:62001'
20 desired_caps['platforVersion']='5.1.1'
21 
22 desired_caps['app']=r'C:\Users\DELL\Downloads\mymoney.apk'
23 desired_caps['appPackage']='com.mymoney'
24 desired_caps['appActivity']='com.mymoney.biz.splash.SplashScreenActivity'
25 
26 driver=webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_caps)
27 driver.implicitly_wait(5)
28 
29 
30 def get_size():
31     x=driver.get_window_size()['width']
32     y=driver.get_window_size()['height']
33     return x,y
34 
35 def swipeLeft():
36     l=get_size()
37     x1=int(l[0]*0.9)
38     y1=int(l[1]*0.5)
39     x2=int(l[0]*0.1)
40     driver.swipe(x1,y1,x2,y1,1000)
41 
42 def swipeUp():
43     l = get_size()
44     x1 = int(l[0] * 0.5)
45     y1 = int(l[1] * 0.95)
46     y2 = int(l[1] * 0.35)
47     driver.swipe(x1, y1, x1, y2, 1000)
48 
49 #等待启动页面元素,然后向左滑动两次,跳过引导页面
50 WebDriverWait(driver,6).until(lambda x:x.find_element_by_id('com.mymoney:id/next_btn'))
51 for i in range(2):
52     swipeLeft()
53     sleep(0.5)
54 #点击“开始随手记”按钮
55 driver.find_element_by_id('com.mymoney:id/begin_btn').click()
56 #检测是否有活动页面弹窗,如果有就点击关闭
57 try:
58     closeBtn=driver.find_element_by_id('com.mymoney:id/close_iv')
59 except NoSuchElementException:
60     pass
61 else:
62     closeBtn.click()
63 
64 #点击设置
65 driver.find_element_by_id('com.mymoney:id/nav_btn_forth').click()
66 #等待界面菜单加载出来,然后向上滑动
67 WebDriverWait(driver,6).until(lambda x:x.find_element_by_id('android:id/content'))
68 swipeUp()
69 #点击高级菜单
70 driver.find_element_by_android_uiautomator('new UiSelector().text("高级")').click()
71 #点击密码与手势密码菜单
72 driver.find_element_by_id('com.mymoney:id/password_protect').click()
73 #点击手势密码保护
74 driver.find_element_by_id('com.mymoney:id/ll_gesture_psd').click()
75 #连续滑动两次设置图案密码
76 for i in range(2):
77     TouchAction(driver).press(x=212, y=296).wait(100)\
78             .move_to(x=148, y=0).wait(100)\
79             .move_to(x=148,y=0).wait(100)\
80             .move_to(x=-148,y=148).wait(100)\
81             .move_to(x=-148,y=148).wait(100)\
82             .move_to(x=148,y=0).wait(100)\
83             .move_to(x=148,y=0).wait(100) \
84             .release().wait(200).perform()

连续滑动设置手势密码坐标计算

首先使用工具获取到元素坐标位置,可以看到起始位置是【138,218】,终点位置是【581,661】

分析:

该图形可以横竖划分六等分

那么第一个圆中心点的坐标:

x=138+(581-138)/6

y=218+(661-218)/6

依次类推,想要画一个z形状,则需要计算第1、2,3,5,7,8,9这几个圆的中心点坐标

然后用TouchAction 的press和moveto方法将几个步骤链接起来。代码如下

 1 #引入包 2 from appium.webdriver.common.touch_action import TouchAction   3 4 def settingPassword(self):5 6         #[138,218][581,661]夜神上的元素坐标  7 8         xxx = (581-138) / 69         one_x = 138 + xxx 
10         one_y = 218 + xxx
11         two_x = 138 + xxx * 3
12         two_y = 218 + xxx #与第二个纵坐标相等
13         three_x=138 + xxx*5
14         three_y=218 + xxx #与第二个纵坐标相等
15         five_x=138 + xxx * 3
16         five_y=218+xxx*3
17         seven_x=138 + xxx
18         seven_y=218+xxx*5
19         eight_x=138 + xxx * 3
20         eight_y=218+xxx*5
21         nine_x=138 + xxx*5
22         nine_y=218+xxx*5
23 
24         TouchAction(self.driver).press(x=one_x, y=one_y).wait(300).move_to(x=two_x, y=two_y).wait(300).move_to(x=three_x,y=three_y).wait(300).move_to(x=five_x,y=five_y).wait(300).move_to(x=seven_x,y=seven_y).wait(300).move_to(x=eight_x,y=eight_y).wait(300).move_to(x=nine_x,y=nine_y).release().perform()

小结

1.实现的时候总是报错:
The coordinates provided to an interactions operation are invalid.

解决方案:在release后边加上wait,即可。这可是查了好多资料,才找到的解决办法,具体原因也有点蒙圈,等找到原因了,后期补上,或者有知道的大佬可以分享一下心得体会 。
期间想不用for循环了,直接写了两个一样的TouchAction还是报错,然后实在是搞不定了,第二天晚上决定既然可以画一个Z字形,要不把设置密码的文章改成解锁密码文章 ,前者需要画两个Z字形,后者需要画一个Z字形。而且刚好解锁,需要一个就可以,内心的小鬼在打架,最终还是理性打败了取巧和任性,硬着头皮解决遇到的各种问题,才有了这篇文章的产生。这也侧面的反应学习和工作是不能偷奸取巧的。                                                                                   

                1 for i in range(2):
2     TouchAction(driver).press(x=212, y=296).wait(100)\
3             .move_to(x=148, y=0).wait(100)\
4             .move_to(x=148,y=0).wait(100)\
5             .move_to(x=-148,y=148).wait(100)\
6             .move_to(x=-148,y=148).wait(100)\
7             .move_to(x=148,y=0).wait(100)\
8             .move_to(x=148,y=0).wait(100) \
9             .release().wait(100).perform()                                                                                                                                                                                           

2.这段代码里面有俩个坑,呃,关键点:
(1)press方法中的坐标为绝对坐标,move_to方法中的坐标都是相对坐标,具体来说第一个move_to中的坐标相对于press方法中的坐标,第二个move_to方法中的坐标相对于第一个move_to方法中的坐标。以此类推下去,以前好像不是这个样子的。直接计算完就可以用了。宏哥期间犯的错误:

  a.就是直接算完就用结果报错;然后查资料说是相对坐标;

  b.然后把后边move_to 的坐标都相对第一个绝对坐标了,结果可想而知,还是报错。

继续查资料,才找到以上的解决办法了。

(2)wait是必须的:这里ms表示为毫秒,ms=100就是等待100毫秒。不用的话太快会出错

3.分成六等份,小伙伴们有点蒙圈,给小伙伴们看一幅比较直观的图

4. 好了,,终于搞定了,获得了新生。


              【下面是我整理的2023年最全的软件测试工程师学习知识架构体系图】


一、Python编程入门到精通

二、接口自动化项目实战

三、Web自动化项目实战


四、App自动化项目实战

五、一线大厂简历


六、测试开发DevOps体系

七、常用自动化测试工具


八、JMeter性能测试

九、总结(尾部小惊喜)

生命不息,奋斗不止。每一份努力都不会被辜负,只要坚持不懈,终究会有回报。珍惜时间,追求梦想。不忘初心,砥砺前行。你的未来,由你掌握!

生命短暂,时间宝贵,我们无法预知未来会发生什么,但我们可以掌握当下。珍惜每一天,努力奋斗,让自己变得更加强大和优秀。坚定信念,执着追求,成功终将属于你!

只有不断地挑战自己,才能不断地超越自己。坚持追求梦想,勇敢前行,你就会发现奋斗的过程是如此美好而值得。相信自己,你一定可以做到!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/12670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【node.js】04-模块化

目录 一、什么是模块化 二、node.js中的模块化 1. node.js中模块的分类 2. 加载模块 3. node.js 中的模块作用域 4. 向外共享模块作用域中的成员 4.1 module对象 4.2 module.exports 对象 4.3 exports对象 5. node.js 中的模块化规范 一、什么是模块化 模块化是指解…

Kafka中的主题(Topic)和分区(Partition)是什么?它们之间有什么关系?

在Kafka中,主题(Topic)和分区(Partition)都是用于组织和存储消息的概念,它们有密切的关系。 主题(Topic):主题是消息的逻辑分类。可以将主题理解为一个逻辑上的消息容器&…

使用python库uvicorn替代Nginx发布Vue3项目

目录 一、Vue3项目打包 二、将打包文件放到python项目 三、配置uvicorn服务 四、启动服务 【SpringBoot版传送门:使用SpringBoot替代Nginx发布Vue3项目_苍穹之跃的博客-CSDN博客】 一、Vue3项目打包 (博主vue版本:3.2.44) 由…

Android平台GB28181设备接入侧如何同时对外输出RTSP流?

技术背景 GB28181的应用场景非常广泛,如公共安全、交通管理、企业安全、教育、医疗等众多领域,细分场景可用于如执法记录仪、智能安全帽、智能监控、智慧零售、智慧教育、远程办公、明厨亮灶、智慧交通、智慧工地、雪亮工程、平安乡村、生产运输、车载终…

2023年自然语言处理与信息检索国际会议(ECNLPIR 2023) | EI Compendex, Scopus双检索

会议简介 Brief Introduction 2023年自然语言处理与信息检索国际会议(ECNLPIR 2023) 会议时间:2023年9月22日-24日 召开地点:中国杭州 大会官网:ECNLPIR 2023-2023 Eurasian Conference on Natural Language Processing and Information Retr…

【Linux】进程通信 — 管道

文章目录 📖 前言1. 通信背景1.1 进程通信的目的:1.2 管道的引入: 2. 匿名管道2.1 匿名管道的原理:2.2 匿名管道的创建:2.3 父子进程通信:2.3.1 read()阻塞等待 2.4 父进程给子进程派发任务:2.5…

Kafka的消息传递模型是什么?

Kafka的消息传递模型采用了发布-订阅模式。它使用了一种分布式的提交日志(commit log)结构来持久化消息,并将消息以主题(topic)的方式进行组织和分类。在这个模型中,消息会被发布到一个或多个主题&#xff…

使用adb通过电脑给安卓设备安装apk文件

最近碰到要在开发板上安装软件的问题,由于是开发板上的安卓系统没有解析apk文件的工具,所以无法通过直接打开apk文件来安装软件。因此查询各种资料后发现可以使用adb工具,这样一来可以在电脑上给安卓设备安装软件。 ADB 就是连接 Android 手…

NFT市场泡沫破裂了吗?投资NFT是否仍然安全?

近期,NFT市场的价格出现了明显的下跌趋势,许多人开始担心NFT市场是否已经进入了泡沫破裂的阶段。但是,我们需要认真分析这个问题,并且探讨投资NFT是否仍然安全。 NFT(Non-Fungible Token)是一种非同质化代币…

LeetCode 436. Find Right Interval【排序,二分;双指针,莫队】中等

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…

perl GetOptions

在Perl中,你可以使用标准模块Getopt::Long来解析命令行选项(Command Line Options)。Getopt::Long模块允许你定义命令行选项以及它们的值,并且还可以处理各种类型的选项,如标志选项(flag options&#xff0…

算法竞赛入门【码蹄集新手村600题】(MT1060-1080)

算法竞赛入门【码蹄集新手村600题】(MT1060-1080) 目录MT1061 圆锥体的体积MT1062 圆锥体表面积MT1063 立方体的体积MT1064 立方体的表面积MT1065 长方体的表面积MT1066 射线MT1067 线段MT1068 直线切平面MT1069 圆切平面MT1070 随机数的游戏MT1071 计算表达式的值M…

网络防御之IDS

1. 什么是IDS? IDS是入侵检测系统,一种对于网络传输进行及时监视,在发现可疑的传输时发出警报或者采取主动反应措施的网络安全设备。IDS是一种积极地主动的防御技术。 2. IDS和防火墙有什么不同? 防火墙是一种隔离并过滤非授权用…

Leetcode-每日一题【剑指 Offer II 075. 数组相对排序】

题目 给定两个数组,arr1 和 arr2, arr2 中的元素各不相同 arr2 中的每个元素都出现在 arr1 中 对 arr1 中的元素进行排序,使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。 示例&…

EtherNet/IP转CAN网关can协议标准

生产管理设备中,会有设备与其他设备的协议不同,数据无法互通,让你的工作陷入困境。这时,一款神奇的产品出现了——远创智控YC-EIP-CAN通讯网关! 1, 这款通讯网关采用ETHERNET/IP从站功能,可以将各种CAN总线…

Lambda表达式

Java Lambda表达式是Java 8中最重要的新特性之一。 它们是一种可传递的匿名函数,可以作为参数传递给方法或存储在变量中,因此可以在需要的时候调用它们。 基础 1. 简介 Lambda表达式的主要目的是简化Java代码,使其更易于阅读和编写。 Lam…

【业务功能篇58】Springboot + Spring Security 权限管理 【中篇】

4.2.3 认证 4.2.3.1 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打卡,当你的指纹和系统里录入的指纹相匹配时&…

前端存储之sessionStorage和localStorage

sessionStorage sessionStorage是一种用于web浏览器中临时保存数据的客户端存储机制。它允许在同一个浏览器窗口的会话期间,保存和访问临时数据,而这些数据在用户关闭窗口或者标签页会被清除。每个sessionStorage对象都与当前的浏览器会话相关联&#x…

12.python设计模式【观察者模式】

内容:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变的时候,所有依赖于它的对象得到通知并被自动更新。观者者模式又称为“发布-订阅”模式。比如天气预报,气象局分发气象数据。 角色: 抽象主题&#xf…

leetcode 122. 买卖股票的最佳时机 II

2023.7.29 把整体利润拆分成每天的利润&#xff0c;将股票值想象成一个折线图&#xff0c;将所有上升的值相加即可。 代码&#xff1a; class Solution { public:int maxProfit(vector<int>& prices) {int ans 0;for(int i1; i<prices.size(); i){if(prices[i]-…