adb的构成和工作原理
- adb的构成
client端,在电脑上,负责发送adb命令
daemon守护进程,在手机上,负责接收和执行adb命令
server端,在电脑上,负责管理client和daemon之间的通信 - adb工作原理
1、client端将命令发送给server端
2、server端会将命令发送给daemon端
3、daemon端进行执行
4、将执行结果,返回给server端
5、servver端将结果在返回给client端
adb获取包名和界面名
-
包名和界面名的概念
1、包名,对应着应用程序
2、界面名,对应着应用程序的某个界面,也叫做启动名 -
如何获取包名和界面名
-
mac
adb shell dumpsys window windows | grep mfocusedApp
- windows
adb shell dumpsys window windows | findstr mfocusedApp
- 应用场景
后期,我们在告诉计算机到底哪一个应用和哪一个界面,必须要使用的一个写代码的参数
adb文件传输
- 从电脑发送文件到手机
如何使用
adb push 电脑的文件路径 手机的文件夹路径
- 从手机拉取文件到电脑
如何使用
adb pull 手机的文件路径 电脑的文件夹的路径
- 应用场景
如果希望将电脑上的某个文件,发送到手机,使用adb push 的命令
如果希望将手机上的某个文件 ,发送到电脑,使用adb pull的命令
获取app启动时间
- 如何获取app启动时间
adb shell am start -w 包名/界面名
- 应用场景
1.当企业有需求的时候,使用这个adb命令进行调试
2.如果企业没有特定的时间规范,我们可以参考同类产品,不要超过一倍即可
获取手机日志
- 如何获取手机日志
adb logcat
- 应用场景
当成发生崩溃的时候,可以将日志信息发送给开发人员,便于其快速的定位bug
关于崩溃的处理,需要找日志中的“at“前面,的第一个字符是E的就是错误信息
adb的其他命令
- 安装app到手机
adb install apk路径
- 卸载手机上的app
adb uninstall 包名
- 查看连接设备的数量及设备号
adb devices
- 进入到android手机系统内部的命令行中
adb shell
- 关闭adb服务
adb kill-server
- 开启adb服务
adb start-server
- 查看adb帮助
adb --help
appium-python库安装
pip3 install Appium-python-client
如何使用appium打开任意一个应用程序
1.打开要测试的应用
2.使用ADB命令获取包名和界面名
3.修改desired_caps字典中的apppackage和appActivity的参数
如果测试的设备版本号发生变化?
修改desired_caps字典中的platformVersion的参数
如果测试的设备平台发生变化?
修改desired_caps字典中的platformName的参数
在脚本内启动其他app
应用场景
如果一个应用需要跳转到另外一个应用,就可以使用这个api进行应用的跳转,就像我们通过外卖应用下订单之后会跳转到支付应用一样
方法名和参数
# 脚本内启动其他app
# 参数
# appPackage:要打开的程序的包名
# appActivity: 要打开的程序的界面名
driver,start_activity(appPackage, appActivity)
示例
from appium import webdriver
import time,os
PATH = lambda p:os.path.abspath(os.path.join(os.path.dirname(__file__),p))
#设备及安装包信息
desired_caps = {
'platformName': 'Android',
'deviceName':'8TB6V4ZPZ54LPJ5P',
'platformVersion': '5.1',
'app': PATH(r'D:\shell_customer-debug.apk'),
'appPackage': 'com.jyibb.shell_customer',
'appActivity': 'com.jyibb.module_launch_customer.SplashActivity',
# 'unicodeKeyboard': 'True',
# 'resetKeyboard': 'True'
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
如何通过代码获取app的包名和界面名
- 通过driver对象调用current_package属性
包名
-通过driver对象调用current_activity
界面名
如何通过代码关闭app和驱动对象?
- 通过driver对象调用close_app方法
关闭当前应用程序,不会关闭驱动对象 - 过driver对象调用quit方法
关闭驱动对象,同事关闭驱动对象所关联的app
如何安装和卸载应用以及判断应用是否安装?
- 安装应用
install_app("apk路径“”)
- 卸载应用
remove_app("包名“)
- 判断某个应用是否已经安装
is_app_installed("包名")
将应用置于后台
应用场景
银行类app会在进入后台一定时间后,如果再回到前台页面会重新输入密码。如果需要自动化测试这种功能,可以使用这个api进行测试
方法
#app放置到后台一定时间后再回到前台,模拟热启动
# 参数
# seconds,后台停留多少秒
driver.background_app(seconds)
使用uiautomatorviewer注意点
1.命令行窗口不要关闭
2.如果uiautomatorviewer 闪退
更换jdk为1.8
3 点击第二个按钮的时候报错
重启adb
- ad kill-server
- adb start-server
如何定位一个元素
- find_element_by_id
传入的参数:resource-id的值 - find_element_by_class_name
传入的参数:class的值 - find_element_by_xpath
传入的参数:xpath表达式 - 注意点:
如果很多元素的“特征“相同,使用find_element_by_xxx的方法会找到第一个
也就是说,尽量去找元素特征有唯一性的“特征“”,来定位。
定位元素的注意点
如果find_element_by_xxx方法,传入了一个没有的条件,会报错,NoSuchElementException
如果find_elements_by_xxx方法,传入了一个没有的条件,不会报错,返回一个空列表
隐式等待
- 关键方法:
通过driver对象调用implicitly_wait方法
设置超时时间 - 作用
在设置了超时时间之后,后续所有的定位元素的方法都会在这个时间内等待的出现。
如果出现了直接进行后续操作
如果没有出现,报错,NoSuchElementException
显式等待
-
关键方法:
关键类:WebDriverWait
关键方法:WebDriverWait对象中的until的方法 -
作用:
在设置了显式等待之后,可以等待一个超时时间,在这个超时时间之内进行查找,默认没0.5秒找一次
0.5秒的频率是可以设置的
一旦找到这个元素,直接进行后续操作
如果没有找到,报错,TimeOutException
隐式等待和 显式等待的选择
-
从使用的角度上:
隐式等待更简单
显式等待相对负责 -
从灵活性的角度上:
显式等待更加灵活,因为可以针对每一个元素进行单独的设置
隐式等待是针对全局的定位元素 -
关于sleep的问题?
sleep不是不能做元素等待,而是不推荐,因为会造成时间上的浪费 -
从选择的角度:
考虑使用的是单个还是全局?
考虑灵活性的问题?
如何去点击元素
- 关键方法
click()
如何对输入框进行问题输入
- 关键方法
send_keys(“要输入的文字”) - 注意点
默认输入中文是有问题的,需要在链接手机的参数中多加两行代码
desired_caps[‘unicodekeyboard’] = True
desired_caps[‘resetkeyboard’] = True
如何对输入框进行文字的清空
- 关键方法
clear()
如何获取文本内容
-
关键属性
text
如何获取元素的位置 -
关键属性
location
是一个字典,字典中有x和y两个key
取到的数据类型是int的
如何获取元素的大小
-
关键属性
- size
- 是一个字典,字典中有width和height两个key
- 取到的数据类型是int的
如何根据元素的属性名获取属性值
-
关键方法
- get_attribute(“属性名”)
-
注意点
- 想要获取resource-id使用resourceid属性名API>=18
- 想要获取class使用className属性名AP》=18
- 想要获取content-desc使用name属性名
- 其他的,都可以参考uiautomator viewer中的属性名
swipe滑动方式
-
方法:
- driver_swipe(起始x坐标,起始y坐标,结束x坐标,结束y坐标,持续时间ms)
-
特点:
- 参数是坐标点
- 持续时间短,惯性大,
- 持续时间长,惯性小
scroll滑动方式
- 方法
- driver.scroll(起始元素,结束元素)
- 特点
- 参数是元素
- 没有持续时间,有惯性
drag_and_drop滑动方式
- 方法:
+driver.drag_adn_drop(起始元素,结束元素) - 特点:参数是元素
- 没有持续时间,没有惯性
三种方式的选择
- 有惯性,传入参数坐标
- swipe,设置较短的持续时间
- 有惯性,传入参数元素
- scroll
- 无惯性,传入参数坐标
- swipe,设置较长的持续时间
- 无惯性,传入参数元素
- drag_and_drop
TouchAction
- 概念和作用
- 高级手势,可以将小的动作组合成一系列复杂的动作
- 步骤:
1.创建TouchAction对象
2.通过对象调用要执行的动作
3.过perform进行执行
轻敲
- 关键方法:
- tap
- 参数:
- 可以传入元素
- 使用element参数
- 可以传入坐标
- 使用x和y参数
- 多次点击
- 使用count参数
- 可以传入元素
按下
- 关键方法:
- press
- 参数:
- 可以传入元素
- 使用el参数
- 可与传入参数
- 使用x和y参数
- 可以传入元素
抬起
- 关键方法:
- release
等待
- 关键方法
- wait
- 参数:
- 等待的时长(毫秒)
- 使用ms参数
- 等待的时长(毫秒)
长按
- 关键方法:
- long-press
- 参数:
- 可以传入元素
- 使用el参数
- 使用传入坐标
- 使用x和y参数
- 设置持续时间
- 使用duration参数(毫秒)
- 可以传入元素
- 额外补充
- 长按<==>按下.等待.抬手.
如何获取手机分辨率
- 关键方法
- driver.get_window_size()
- 返回值:
- 字典
- 里面有两个key。分别是width和height
- 宽和高的值是int类型的
如何截图
- 关键方法
- driver.get_screenshot_as_file
- 参数
- 文件的路径
- 如果直接写了文件名,则会默认保存在项目下
如何获取和设置当前手机的网络
- 获取网络状态
- 属性
- network_connection
- 设置网络状态
- 方法
- setnetwork_connection
- 参数
- 网络类型
- 方法
- 属性
注意点:
网络的类型,建议使用系统提供的类型
from appium.webdriver.connectiontype import connectionType
发送键到设备
- 关键方法
- driver.press_keycode
- 参数
- 按键对应的编码
- 参考的keycode
- https://blog.youkuaiyun.com/feizhixuan46789/article/cletails/16801429
操作通知栏
- 打开
- driver.open_notifications
- 关闭
- 使用返回键
- press_keycode(4)