Appium手机自动化
Appium用途和特点
Appium简介
Appium
是一个移动 App (手机应用)自动化工具。
手机APP 自动化有什么用?
- 自动化完成一些重复性的任务,比如:微信客服机器人
- 爬虫:就是通过手机自动化爬取信息。为什么不通过网页、HTTP 爬取呢?有的系统没有网页,也不方便通过HTTP爬取。
- 自动化测试:很多企业里面有这样的需求
Appium
自动化方案的特点
- 开源免费
- 支持多个平台:iOS (苹果)、安卓 App 的自动化都支持。
- 支持多种类型的自动化
- 支持 苹果、安卓 应用 原生界面 的自动化
- 支持 应用 内嵌 WebView 的自动化
- 支持 手机浏览器 中的 web网站自动化
- 支持 flutter 应用的自动化
- 支持多种编程语言:像 Selenium 一样, 可以用多种编程语言调用它开发自动化程序。
Appium自动化原理
Appium自动化原理图
包含了 3个主体部分 : 自动化程序、Appium Server、移动设备
自动化程序
- 自动化程序是由我们来开发的,实现具体的手机自动化功能。
- 要发出具体的指令控制手机,也需要使用客户端库。
- 和Selenium一样,Appium 组织也提供了多种编程语言的客户端库,包括 Java,Python,JS, Ruby等,方便不同编程语言的开发者使用。
- 我们需要安装好客户端库,调用这些库,就可以发出自动化指令给手机。
Appium Server
Appium Server 是 Appium 组织开发的程序,它负责管理手机自动化环境,并且转发自动化程序的控制指令给手机,并且转发手机给自动化程序的响应消息。
手机设备
- 我们这里说的手机设备,其实不仅仅是手机,包括所有苹果、安卓的移动设备,比如:手机、平板、智能手表等。
- 为了直观方便的讲解,这里我们简称: 手机
- 当然手机上也包含了我们要自动化控制的手机应用APP。
- 手机设备为什么能接收并且处理自动化指令呢?
- 因为,Appium Server 会在手机上安装一个自动化代理程序, 代理程序会等待自动化指令,并且执行自动化指令
原理示例
比如:要模拟用户点击界面按钮,Appium 自动化系统的流程是这样的:
- 自动化程序调用客户端库相应的函数, 发送
点击元素
的指令(封装在HTTP消息里)给 Appium Server - Appium Server 再转发这个指令给手机上的自动化代理
- 手机上的自动化代理接收到指令后,调用手机平台的自动化库,执行点击操作,返回点击成功的结果给 Appium Server
- Appium Server 转发给自动化程序
- 自动化程序了解到本操作成功后,继续后面的自动化流程
其中,自动化代理控制,使用的什么库来实现自动化的呢?
- 如果测试的是苹果手机, 用的是苹果的 XCUITest 框架 (IOS9.3版本以后)
- 如果测试的是安卓手机,用的是安卓的 UIAutomator 框架 (Android4.2以后)
- 这些自动化框架提供了在手机设备上运行的库,可以让程序调用这些库,像人一样自动化操控设备和APP,比如:点击、滑动,模拟各种按键消息等。
Appium自动化环境搭建(安卓)
安装client编程库
因为我们介绍Python语言开发,所以当然是用pip安装,安装命令如下
1 | pip install appium-python-client |
安装Appium Server
- Appium Server 是用Node.js运行的,基于js开发出来的。
- Appium组织为了方便大家安装使用,制作了一个可执行程序 Appium Desktop,把Node.js运行环境、Appium Server 和一些工具打包在里面了,只需要简单的下载安装就可以了。
- 可以从上面给出的下载链接下载安装:
Appium-windows-1.21.0.exe
安装JDK
- 本教程主要讲解安卓APP的自动化,必须要安装安卓SDK(后面会讲到),而安卓SDK需要 JDK 环境。
- 可以从上面给出的下载链接下载安装:
jdk-16.0.1_windows-x64_bin.exe
- 安装好之后,还需要添加一个环境变量
JAVA_HOME
,指定值为JDK安装目录,比如:1
JAVA_HOME C:\Program Files\Java\jdk-16.0.1
安装 Android SDK
- 对于安卓App的自动化,Appium Server 是需要Android SDK的。
- 因为要用到里面的一些工具,比如要执行命令设置手机、传送文件、安装应用、查看手机界面等。
- 可以从上面给出的下载链接下载安装(Android 11):
android-sdk-windows.rar
- 安装教程
- 解压完成后,需要配置一下,添加一个环境变量
ANDROID_HOME
,设置值为SDK包解压目录,比如:1
ANDROID_HOME D:\Program Files (x86)\android-sdk-windows
- 另外,还推荐大家配置环境变量 PATH ,加入adb所在目录,如:
1
PATH D:\Program Files (x86)\android-sdk-windows\platform-tools
⚠️注意:是
添加
该目录到环境变量PATH中,!!!不是替换!!!
,否则会导致系统命令都找不到的严重后果。
连接手机
上述的软件环境都准备好以后,要自动化手机APP,需要:
- 在你运行程序的电脑上用 USB 线连接上你的安卓手机
- 进入
手机设置
->关于手机
,不断点击版本号
菜单(7次以上) - 退出到上级菜单,在开发者模式中,启动USB调试
如果手机连接USB线后,手机界面弹出类似如下提示,请选择 允许 USB调试。
⚠️注意:
- 有的手机系统,可能需要一些额外的选项需要设置好。
- 比如,有的手机,开发者选项里需要打开
允许通过USB安装应用
等。 - 总之,给USB开发调试尽可能方便的控制手机。
连接好以后,打开命令行窗口, 执行 adb devices -l
命令来列出连接在电脑上的安卓设备。
如果输出类似如下的内容:
1 | List of devices attached |
表示电脑上可以查看到连接的设备,就可以运行自动化程序了。
代码示例
使用 Appium 自动化的打开B站应用
1 | import time |
运行代码前,先要
运行Appium Desktop
;报错参考链接
查找appPackage和appActivity
没有apk安装包
如果你应用已经安装在手机上了,可以直接打开手机上该应用,进入到你要操作的应用界面,然后在 命令提示符 界面下执行以下代码:
1 | adb shell dumpsys activity recents | find "intent={" |
⚠️注意:如果在“PowerShell”界面下执行该语句,可能会报错。
结果显示如下,最近的几个activity信息:
1 | intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=tv.danmaku.bili/.ui.splash.SplashActivity} |
其中第一行就是当前的应用,我们特别关注最后
1 | cmp=tv.danmaku.bili/.ui.splash.SplashActivity |
- 应用的appPackage名称就是:
tv.danmaku.bili
- 应用的appActivity名称就是:
.ui.splash.SplashActivity
有apk安装包
如果你已经获取到了apk安装包,需要首先切换到aapt.exe目录下,如:D:\Program Files (x86)\android-sdk-windows\build-tools\30.0.3
,然后在 命令提示符 界面下运行以下代码:
1 | aapt.exe dump badging C:\Users\suyin\Desktop\iBiliPlayer-bili.apk | find "package: name=" |
输出信息中,就有appPackage名称
1 | package: name='tv.danmaku.bili' versionCode='6262000' versionName='6.26.2' compileSdkVersion='30' compileSdkVersionCodename='11' |
在 命令提示符 界面下运行以下代码:
1 | aapt.exe dump badging C:\Users\suyin\Desktop\iBiliPlayer-bili.apk | find "launchable-activity" |
输出信息中,就有应用的启动appActivity
1 | launchable-activity: name='tv.danmaku.bili.ui.splash.SplashActivity' label='' icon='' |
⚠️注意事项:
- 一定要记得首先切换目录到aapt.exe目录下
- 要在 命令提示符 界面运行以上代码
- 如果在“PowerShell”界面下执行该语句,可能会报错
C:\Users\suyin\Desktop\iBiliPlayer-bili.apk
是你下载的apk安装包的路径
定位元素
代码规则
和Selenium Web自动化一样,要操作界面元素,必须先定位(选择)元素。
find_element_by_XXX
方法,返回符合条件的第一个元素,找不到抛出异常find_elements_by_XXX
方法,返回符合条件的所有元素的列表,找不到返回空列表- 通过
WebDriver
对象调用这样的方法,查找范围是整个界面 - 通过
WebElement
对象调用这样的方法,查找范围是该节点的子节点
界面元素查看工具
-
简介
- 做 Selenium Web 自动化的时候,要找到元素,我们是通过浏览器的开发者工具栏来查看元素的特性,根据这些特性(属性和位置),来定位元素
- Appium 要自动化手机应用,同样需要工具查看界面元素的特征
- 常用的查看工具是: Android SDK包中的
uiautomateviewer
和 Appium Desktop 中的Appium Inspector
-
uiautomateviewer
- 安卓查看APP界面元素,最常用的就是 Android SDK 中的工具
uiautomateviewer
,它在SDK目录中的 tools\bin 目录中,如:D:\Program Files (x86)\android-sdk-windows\tools\bin
- 和Selenium一样,我们要定位选择元素,也是根据元素的特征,包括
- 元素的属性
- 元素的相对位置(相对父元素、兄弟元素等)
- 使用uiautomateviewer报错,解决方案链接
- uiautomateviewer使用视频教程:前13分钟(0-13分钟)
- 安卓查看APP界面元素,最常用的就是 Android SDK 中的工具
-
Appium Inspector
- Appium Desktop 中的
Appium Inspector
也可以查看元素 - 它的一个优点是可以直接验证选择表达式是否能定位到元素
- Appium Inspector使用视频教程:后13分钟(13-26分钟)
- Appium Desktop 中的
定位元素的方法
-
根据ID
- 在Selenium Web自动化教程里,我们说过,如果能根据ID选择定位元素,最好根据ID,因为通常来说ID是唯一的,所以根据ID选择效率高。
- 在安卓应用自动化的时候,同样可以根据ID查找。
- 但是这个ID ,是安卓应用元素的
resource-id
属性 - 使用如下代码
1
driver.find_element_by_id('expand_search')
-
根据CLASS NAME
- 安卓界面元素的class属性其实就是根据元素的类型,类似web里面的tagname, 所以通常不是唯一的。
- 通常,我们根据class属性来选择元素, 是要选择多个而不是一个。
- 当然如果你确定要查找的界面元素的类型在当前界面中只有一个,就可以根据class来唯一选择。
- 使用如下代码
1
driver.find_elements_by_class_name('android.widget.TextView')
-
根据ACCESSIBILITY ID
- 元素的 content-desc 属性是用来描述该元素的作用的。
- 如果要查询的界面元素有content-desc属性,我们可以通过它来定位选择元素。
- 使用如下代码
1
driver.find_element_by_accessibility_id('搜索查询')
-
Xpath
- Appium 也支持通过Xpath选择元素。
- 但是其可靠性和性能不如Selenium Web自动化。因为Web自动化对Xpath的支持是由浏览器实现的,而Appium Xpath的支持是Appium Server实现的。毕竟,浏览器产品的成熟度比Appium要高很多。
- 当然,Xpath是标准语法,所以这里表达式的语法规则和以前学习的Selenium里面Xpath的语法是一样的,比如:
1
driver.find_element_by_xpath('//ele1/ele2[@attr="value"]')
- 注意:
- Selenium自动化中, Xpath表达式中每个节点名是html的tagname。
- 但是在Appium中, Xpath表达式中每个节点名是元素的class属性值。
- 比如:要选择所有的文本节点,就使用如下代码:
1
driver.find_element_by_xpath('//android.widget.TextView')
-
安卓 UI Automator
- 根据id,classname, accessibilityid,xpath,这些方法选择元素,其实底层都是利用了安卓 uiautomator框架的API功能实现的。
- 参考这里的谷歌安卓官方文档介绍
- 也就是说,程序的这些定位请求,被Appium server转发给手机自动化代理程序,就转化为uiautomator里面相应的定位函数调用。
- 其实,我们的自动化程序,可以直接告诉手机上的自动化代理程序,让它调用UI Automator API的java代码,实现最为直接的自动化控制。
- 主要是通过 UiSelector 这个类里面的方法实现元素定位的,比如:
1
2
3code = 'new UiSelector().text("热门").className("android.widget.TextView")'
ele = driver.find_element_by_android_uiautomator(code)
ele.click()就是通过 text 属性和 className的属性两个条件来定位元素
- UiSelector里面有些元素选择的方法可以解决前面解决不了的问题,比如:
text
方法:可以根据元素的文本属性查找元素textContains
:根据文本包含什么字符串textStartsWith
:根据文本以什么字符串开头textmartch
:可以使用正则表达式 选择一些元素,如下1
code = 'new UiSelector().textMatches("^我的.*")'
- UiSelector 的
instance
和index
也可以用来定位元素,都是从0开始计数, 他们的区别:- instance是匹配的结果所有元素里面的第几个元素
- index则是其父元素的几个节点,类似Xpath里面的*[n]
- UiSelector 的
childSelector
可以选择后代元素,比如1
2
3code = 'new UiSelector().resourceId("tv.danmaku.bili:id/recycler_view").childSelector(new UiSelector().className("android.widget.TextView"))'
ele = driver.find_element_by_android_uiautomator(code)注意:childSelector后面的引号要框住整个子 uiSelector 的表达式;目前有个bug:只能找到符合条件的第一个元素,参考appium在github上的 issues
界面操作和 adb 命令
界面操作
-
click点击
最常见的操作之一,使用 WebElement 对象的
click
方法,示例代码中已展示,在此不再赘述 -
tap点按
- WebElement 对象的
tap
方法和 click 类似,都是点击界面 - 但是最大的区别是, tap是
针对坐标
而不是针对找到的元素 - 为了保证自动化代码在所有分辨率的手机上都能正常执行,我们通常应该使用click方法
- 但有的时候,我们难以用通常的方法定位元素, 可以用这个tap方法,根据坐标来点击
- 既然tap是用坐标来点击界面的,我们怎么知道这个元素的坐标呢?
- 大家还记得用inspect查看该元素的属性中,有一个
bounds
属性吗? - 它就是表示元素的左上角,右下角坐标的 坐标
- 我们还可以使用 UIAutomatorviewer 直接光标移动,看右边的属性提示
- 大家还记得用inspect查看该元素的属性中,有一个
- tap 方法可以像这样进行调用
1
driver.tap([(850,1080)],300)
- 它有两个参数:
- 第一个参数是个列表,表示点击的坐标
- 注意最多可以有5个元素,代表5根手指点击5个坐标。所以是list类型
- 如果我们只要模拟一根手指点击屏幕,list中只要一个元素就可以了
- 第二个参数表示tap点按屏幕后停留的时间
- 如果点按时间过长,就变成了长按操作了
- 第一个参数是个列表,表示点击的坐标
- WebElement 对象的
-
输入
最常见的操作之一, 使用 WebElement 对象的
send_keys
方法, 示例代码中已展示,在此不再赘述 -
获取界面文本信息
可以通过 WebElement 对象的
.text
属性获取该对象的文本信息,示例代码中已展示,在此不再赘述 -
滑动
- 我们做移动app测试的时候,经常需要滑动界面,怎么模拟滑动呢? WebDriver对象的 swipe方法,就提供了这个功能,比如:
1
driver.swipe(start_x=x, start_y=y1, end_x=x, end_y=y2, duration=800)
- 前面4个参数是:滑动起点和终点的x、y坐标
- 第5个参数duration是滑动从起点到终点坐标所耗费的时间
- ⚠️注意:这个时间非常重要,在屏幕上滑动同样的距离,如果时间设置的很短,就是快速的滑动
- 比如:一个翻动新闻的界面,快速的滑动,就会是扫动的动作,会导致内容
惯性
滚动很多
- 我们做移动app测试的时候,经常需要滑动界面,怎么模拟滑动呢? WebDriver对象的 swipe方法,就提供了这个功能,比如:
-
按键
- 前面的示例代码中已经使用过调用
press_keycode
方法,就能模拟按键动作,包括安卓手机的实体按键和键盘按钮 - 如下代码所示
1
2
3
4from appium.webdriver.extensions.android.nativekey import AndroidKey
# 输入回车键,确定搜索
driver.press_keycode(AndroidKey.ENTER) - 按键定义,参考文档
- 前面的示例代码中已经使用过调用
-
长按、双击、移动
- Appium的 TouchAction 类提供了更多的手机操作方法,比如:长按、双击、移动
- 参考源代码中的注释
- 比如,下面就是一个长按的例子
1
2
3
4
5from appium.webdriver.common.touch_action import TouchAction
# ...
actions = TouchAction(driver)
actions.long_press(element)
actions.perform()
-
查看通知栏
-
打开通知栏
- 安卓手机, 查看通知栏的动作可以是从屏幕顶端下滑来查看通知
- 我们刚刚学过滑动,感兴趣的朋友可以自己试试,关键是要找对滑动的起始点和滑动距离
- 更方便的,我们可以使用如下代码,直接打开通知栏
1
driver.open_notifications()
- 通知栏里面的元素,自动化的方法和前面介绍的App界面元素自动化是一样的
-
收起通知栏
- 收起通知栏,可以使用前面介绍的模拟按键, 发出返回按键的方法
-
adb命令
-
adb简介
- 这里我们给大家介绍一个android sdk里面的命令行工具
adb
,adb 全称Android Debug Bridge
,这个adb 使用非常广泛,它可以与 Android 手机设备进行通信,它可进行各种设备操作。 - 比如: 安装应用和调试应用,传输文件,甚至登录到手机设备上shell的进行访问,就像远程登录一样
- 这个adb 在sdk的
platform-tools
目录下面, 请大家确保路径在path环境变量中 - Appium对Android的自动化就非常依赖这个adb工具。 执行自动化过程中,有很多内部操作,比如获取设备信息,传送文件到手机,安装apk,启动某些程序等,都是通常这个adb实现的
- 大家想想我们学习了adb命令,对我们的自动化程序有什么用例呢?
- 既然这是个命令,就可以使用 Python的
os.system()
或者subprocess
来自动化调用它,完成我们的各种自动化需求 - 比如,我们自动化过程中,可能需要截屏手机,并且下载到指定目录中,就可以在我们的Python程序中这样写
1
2
3import os
os.system('adb shell screencap /sdcard/screen3.png && adb pull /sdcard/screen3.png') - 特别是,还可以通过adb使用am(activity manager)和pm(package manager)两个工具, 可以启动 Activity、强行停止进程、广播 intent、修改设备屏幕属性、列出应用、卸载应用等
- adb命令官方文档
- 这里我们给大家介绍一个android sdk里面的命令行工具
-
查看连接的设备
1
adb devices -l
-
列出文件和传输文件
-
查看目录
1
adb shell ls /sdcard
-
上传
1
adb push wv.apk /sdcard/wv.apk
-
下载
1
adb pull /sdcard/new.txt
-
-
截屏
1
adb shell screencap /sdcard/screen.png
截屏后的文件存在手机上,可以使用 adb pull 下载下来
-
shell
- 登录到手机设备上shell的进行访问,就像远程登录一样,可用来在连接的设备上运行各种命令
- 大家可以执行一下 adb shell 然后执行各种安卓支持的 Linux命令,比如 ps、netstat、netstat -an|grep 4724、 pwd、 ls 、cd 、rm 等
- 执行quit退出 shell
内嵌网页自动化
准备工作
- 内嵌网页教程示例App下载
-
大家在我提供的下载链接上下载并安装一款教程示例App:
wv.apk
内嵌网页的混合App
- 很多移动App 都是
Hybrid(混合)
应用。混合应用主要是指它的一部分是原生界面和代码,而另一部分是内嵌网页 ,现在基本上需要打开网页浏览的app都是混合app,比如微信、支付宝等。微信的sms界面是原生代码实现的,而打开某个朋友圈,或者别人发来的的链接部分则是 web部分。 - App中的内嵌的展示网页内容的模块,我们称之为
webview
- 我们自动化的时候如果需要操作内嵌webview中的网页内容,该怎么做呢?
修改编译App
-
前面讲过,Appium 的原则是不修改应用本身,就可以对应用进行自动化。但是,这里要违背一下Appium的原则,要对App内嵌网页进行自动化,首先要请开发人员修改源代码,保证对webview 对象加入setWebContentsDebuggingEnabled 的调用
-
安卓应用,修改java代码,如下所示
1
2
3
4
5
6
7protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 找到 webview 对象
WebView myWebView = (WebView) findViewById(R.id.jcywebview);
// 添加打开 webview内容debug开关
myWebView.setWebContentsDebuggingEnabled(true);
}; -
然后,编译出一个支持自动化的版本,否则无法对webview中的内容进行自动化操作
用Chrome查看App内嵌网页
-
简介
- 编译产生了支持自动化的App,接下来我们就可以安装到手机上,进行内嵌网页的自动化了
- App内嵌网页的自动化,也是使用 Selenium。 和电脑上自动化Chrome浏览器本质是一样的,因为安卓手机内嵌的webview基本上就是手机版的Chrome浏览器,但是,因为网页内容在手机中呈现,不能像电脑浏览器那样,打开开发者工具,查看元素内容
- 那我们怎么查看元素的属性特征,来定位选择元素呢?
- 这里面要分两种情况:
- webview不依赖App环境
- webview依赖App环境
-
webview不依赖App环境
这种情况下App的内嵌 webview
和 native部分是没有交互
的,webview 只是打开一个固定的网址(一般是该公司的手机网址)而已,这种情况,我们要查看webview内容非常简单,因为其实和手机没有关系,直接用Chrome浏览器F12里面的手机模式打开对应的网页,即可,如图所示: -
webview依赖App环境
- 这种情况下App的内嵌 webview
和 native部分是有交互
的, 它必须在app中才能运行,这种情况,我们直接打开网页url运行不起来(或者说运行结果和在app中不同), 甚至,我们根本就不知道网页的url。怎么办? - 这时候,我们可以通过Chrome浏览器的远程调试功能,⚠️注意:这种方法,一定要你的网络环境能访问谷歌!!!
- 假设你的网络环境是可以连接谷歌的:
- 首先,确保我们的应用运行
- 然后,打开Chrome浏览器,地址栏输入
chrome://inspect
,出现如下所示界面
- ⚠️注意:上图红框内是webview版本。有的手机比较老 ,webview版本也比较老的,就会有问题, 尽量使用新手机进行自动化
- 点击 inspect即可查看,如下图所示
- 具体操作,可以参考官方文档
- 这种情况下App的内嵌 webview
自动化代码
- 请大家运行前文下载的 wv App,界面如下
- 这个App内置了一个 webview,这个webview缺省就是打开百度的网址,和native代码没有交互, 完全可以用浏览器直接以手机模式查看网页元素
- 我们假设要做的就是在这个应用,进入webview里面的百度,搜索关键字
白月黑羽
, 我们看看代码怎么实现。前面已经说过,webview自动化代码和电脑上浏览器的自动化基本差不多,但是有一点要注意:手机App中 webview里面的网页内容, 是在一个独立于应用native部分的环境里面的;而缺省情况下,find_element_by_xxx 这样的代码选择元素,Appium 只会在 native 部分的界面寻找元素,肯定找不到元素。 - Appium 把一个界面环境称之为一个
context
,native 部分的 context 名字为NATIVE_APP
,而webview部分的context则为WEBVIEW_XXX
(XXX部分是应用的app package名) - 我们怎么查看当前有哪些context呢?
- 我们的代码通过 driver 对象的
contexts
属性来获取,也就是driver.contexts
- driver 对象的
current_context
属性对应当前的 context 对象
- 我们的代码通过 driver 对象的
- 大家可以打开自动化代码, 添加如下内容
1
print(driver.contexts)
- 执行一下,解释一下,可以发现结果如下
1
2
3
4[
'NATIVE_APP',
'WEBVIEW_com.example.jcy.wvtest'
] - 我们的应用中, webview 的 context 就是 WEBVIEW_com.example.jcy.wvtest,而当前的context 是’NATIVE_APP’, 所以当前的自动操作都是在native context里面的进行的,要对该webview里面的网页内容进行自动化操作,必须先将当前的context切换为webview的context,怎么切呢?
- 使用
switch_to.context
1
driver.switch_to.context('WEBVIEW_com.example.jcy.wvtest')
- 使用
- 好,现在我们修改代码,如下所示
1
2
3
4
5driver.switch_to.context('WEBVIEW_com.example.jcy.wvtest')
driver.find_element_by_id('index-kw').send_keys('白月黑羽')
driver.find_element_by_id('index-bn').click() - 执行一下,发现可以自动化了,那么怎么切换回 native app 进行自动化呢?
- 当然是继续使用
switch_to.context
,如下1
driver.switch_to.context('NATIVE_APP')
- 当然是继续使用
- 大家可以查看一下,app界面上
B站
和QQ
的 id 分别为:navigation_bili 和 navigation_qq - 如果我们想再切换回native部分,分别点击底部导航栏
B站
按钮和QQ
按钮,就可以修改代码如下1
2
3
4driver.switch_to.context('NATIVE_APP')
driver.find_element_by_id('navigation_bili').click()
time.sleep(2)
driver.find_element_by_id('navigation_qq').click()
手机浏览器网页自动化
- 有的公司开发了手机版网站,直接用手机浏览器打开的,比如:xiaomi、京东等,并不是手机App,这种手机网页,我们怎么程序自动化呢?
- 首先,必须在手机上安装谷歌浏览器。以百度为例,首先启动 Appium Desktop。然后,我们的自动化程序代码如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '7'
desired_caps['deviceName'] = 'test'
desired_caps['browserName'] = 'Chrome'
desired_caps['newCommandTimeout'] = 6000
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
driver.implicitly_wait(10)
try:
driver.get('http://www.baidu.com')
driver.find_element_by_id('index-kw').send_keys('白月黑羽')
driver.find_element_by_id('index-bn').click()
except:
print(traceback.format_exc())
webview、驱动版本配套
-
问题
- 大家知道,基于 Appium 的安卓应用自动化时,如果要自动化的app里面内嵌网页内容, Appium会使用基于Selenium的自动化机制
- 安卓app里面的网页,基本上都是使用手机系统上的webview去显示的,安卓 webview 可以看成是手机上的 Chrome 浏览器精简版
- 我们知道 Selenium 自动化 Chrome 浏览器,需要使用相应版本的浏览器驱动,Chrome 浏览器和 chromedriver 的配套关系可以在下面这个链接查看到:Chrome浏览器和chromedriver版本配套表
- Appium Desktop 里面内置了用于 webview 自动化的chromedriver。 比较新的Appium server, 内置chromedriver也是比较新的,而自动化的手机如果比较老, 那么手机里面的webview版本也会比较老,这是就会出现和新版本的Appium Desktop里面的 chromedriver 不匹配的问题。 自动化程序运行时, appium 会报类似如下错误
- 上面的错误,就是说你的手机webview版本是 58, 而你的Appium Desktop里面的 chromedriver 版本又是比较新的, 对这个老版本的webview就不匹配了
-
解决方案
- 这时,我们可以根据配套表
- 下载对应的老版本的chromedriver 2.31,然后设置Appium Desktop使用这个版本的 chromedriver
- 如下图所示,先点击 Advanced 设置项,然后在下图位置写上你的老版本的 chromedriver 的路径
- 这时,我们可以根据配套表