Appium环境搭建
1、启动逍遥模拟器
2、adb连接:cmd中adb connect 127.0.0.1:21503 (逍遥模拟器)
1. 安装篇
工具 |
作用 |
当前版本号 |
安装方式 |
JDK |
Java开发工具包 |
1.8.0_181 |
电脑管家 |
Android SDK |
Android开发工具包 |
|
SDK Manager |
逍遥模拟器 |
模拟手机 |
逍遥模拟器7.6.1 |
电脑管家 |
node.js |
javaScript解析器 |
V10.16.3 |
官网下载 |
Appium |
不再更新,与下面Appium-desktop二选一即可,建议使用desktop |
V1.4.16.1 |
官网下载 |
Appium-desktop |
Appium Server GUI,可识别toast |
V1.22.0 |
github下载 |
Appium-Inspector |
元素定位 |
2021.9.2 |
github下载 |
Python |
|
V38.5 |
官网下载 |
Appium-Python-Client |
python三方模块 |
|
pip安装 |
pycharm |
python编辑器 |
2018.2.4 |
官网下载 |
1.1. JDK安装
JDK下载安装、环境变量配置
1.2. Android SDK
SDK:Software Development Kit
API:Application Program Interface
adb:Android Debug Bridge
SDK基础工具包下载、SDK相关tools及API下载、环境变量配置
方法一:https://www.androiddevtools.cn/ 下载android sdk相关工具
1. 选择SDK Tools,此为sdk基础包,《android-sdk_r24.4.1-windows.zip》解压
2. 选择build-tools,《21.1.2.rar》解压后文件夹放在android-sdk-windows\build-tools(新建该文件夹)下
3. 选择platform-tools,此为adb, fastboot平台工具包,《platform-tools》解压后文件夹放在android-sdk-windows下
4. 选择SDK,此为plastform(api)版本,《android-21.rar》解压后文件夹放在android-sdk-windows\platforms下,API版本为21,对应platform版本为5。
5.打开SDK Manager,打开 Tools(工具)菜单选择 Options(选项)菜单项打开Android SDK Manager Setting对话框,点击 Clear Cache(清除缓存)按钮,然后重启Eclipse(或Android Studio)和SDK Manager。
6. 添加环境变量
系统环境变量中添加
ANDROID_HOME=D:\android-sdk-windows
系统环境变量path中添加:
%ANDROID_HOME%;%ANDROID_HOME%/tools;%ANDROID_HOME%/platform-tools
方法二、详见博客《Android SDK环境搭建》
1.3. 安装node.js
官网下载:https://nodejs.org/en/download/
安装完成后,运行cmd,输入node –v查看版本号
1.4. 安装Appium-desktop
由于Appium版本只更新到1.4.16后面已不再更新,现在使用Appium-Server-GUI,也即Appium-desktop来驱动App。该版本可以识别toast。
安装appium-uiautomator2-driver
安装appium-uiautomator2-driver使用命令cnpm install xx 来安装,如果在cmd中输入cnpm -v 不支持该命令,需要先安装cnpm。
安装cnpm命令:
即npm全局环境变量配置。
1、安装完node之后,在nodejs目录下创建两个文件夹node_cache和node_global;
2、通过cmd 命令行分别执行以下命令:
npm config set prefix “D:\Program Files\nodejs\node_global”
npm config set cache “D:\Program Files\nodejs\node_cache”
npm install -g cnpm --registry=https://registry.npm.taobao.org
3、将node_global加入path环境变量中
D:\Program Files\nodejs\node_global
4、打开cmd输入cnpm -v 有信息说明可以用cnpm了
5、cmd执行cnpm install express -g
6、增加环境变量NODE_PATH,地址为
D:\Program Files\nodejs\node_global\node_modules
安装appium-uiautomator2-driver
cnpm install appium-uiautomator2-driver
安装Appium-desktop
1、下载:在github下载Appium-Server-GUI-windows-1.22.0版本,该版本支持识别toast。
下载链接:https://github.com/appium/appium-desktop/releases
2、使用Appium-desktop需要做如下改动:
(1)脚本desired_caps中添加automationName=UiAutomator2; 修改platformVersion的值:'platformVersion': '7'
(2)D:\Programs\android-sdk-windows\platform-tools中添加apksigner.jar
1.5. 安装Appium服务端(与1.4二选一即可)
官网下载:https://bitbucket.org/appium/appium.app/downloads/
完整安装带UI的appium,可以从官网直接下载zip(Windows)或者dmg(for mac),运行里面的exe即可。
环境变量
找到这个文件安装目录XX\appium\node_modules\.bin加到环境变量path下
appium-doctor检查是否安装成功
如果报错:JAVA_HOME is set but does not exist…
解决:JAVA_HOME系统环境变量后面多了分号;通过编辑文本将分号去掉。
1.6. 安装python
下载Python安装包进行安装。
1.7. 安装Appium-Python-Client
pip install Appium-Python-Client
或者 pip3 install Appium-Python-Client
1.8. 安装pycharm
--本地已安装,版本:PyCharm2018.2.4(Community Edition)
--安装方法参见网上
2. 使用基础篇
2.1.获取deviceName
2.1.1.真机
手机通过数据线连接电脑,在cmd中输入adb devices
2.1.2.逍遥模拟器
adb connect 127.0.0.1:21503
adb devices
图片导入模拟器
将图片拷贝到模拟器路径下,这样在上传照片,相册选择时可以选择到
2.1.3. 夜神模拟器
-adb connect 127.0.0.1:62001
-adb devices
nox_adb.exe connect 127.0.0.1:62001
2.2. 获取apk包名和activity
方法一:有APK包时,使用aapt
如果没有安装则通过SDK Manager安装并设置环境变量
aapt dump badging E:\apk安装包\app-pd-autotest.apk
方法二:cmd窗口使用adb shell命令
查package—pm list package
#仅查看第三方的apk package
adb shell pm list package -3 -f
#查看当前device中所有apk对应的package
adb shell pm list package -f
查询Activity--dumpsys
手机上只打开测试的APP,然后cmd输入以下命令
adb shell dumpsys window w | findstr mCurrent
注意:cmd terminal的查找命令在linux和mac操作系统中对应关键字时grep,在Windows操作系统中对应关键字是 findstr
2.3. 启动Appium-Server-GUI
启动Appium Server GUI,设置Host为127.0.0.1,该host应该与脚本中相同。
点击Start Server
2.4. 启动Appium(与2.3二选一)
1、打开Appium.exe,点击右上角三角,启动appium后,右上角变成正方形就是启动状态
2、appium启动查看platformName和platformVersion
2.4. 编写测试脚本
1、 在pycharm中编写python脚本testCase01.py
安卓真机:
from appium import webdriver # 此时手机已安装apk包 desired_caps = { 'platformName': 'Android', # Appium界面获取 'deviceName': 'DRB5T18717004121', # NOVA3 真机,adb devices获取 'platformVersion': '23', # Appium界面获取 'appPackage': 'com.xx.xxx', # apk包名,由aapt dump badging命令获取 'appActivity': 'com.xx.activity.login.SplashActivity' # apk launchable-activity,由aapt命令获取 } driver = webdriver.Remote('127.0.0.1:4723/wd/hub', desired_caps)
逍遥模拟器
from appium import webdriver desired_caps = { 'platformName': 'Android', 'deviceName': '127.0.0.1:21503', 'platformVersion': '23', 'appPackage': 'com.xx.snack', 'appActivity': 'com.xx.snack.SyncDataActivity' }
webdriver.Remote地址是从appium设置里获取的
3、在pycharm中运行python脚本,如果不报错直接进行下一步;
如果报错,参照最下面《问题汇总》
4、运行成功后在Appium中查看日志
5、运行成功后在手机或模拟器上会多出如下图标,Appium-desktop只多出Appium Setting
3.定位篇
3.2 控件定位-Appium-Inspector
Appium-desktop点击右上角搜索
如图中提示信息:Inspector现作为独立app发布。
1、点击按钮进入github下载Appium-Inspector:Appium-Inspector-windows-2021.9.2
2、启动Appium Inspector.exe
3、填写Desired Capablities 并保存
4、下次启动直接选择保存的session启动
3.3.元素定位-UI Automator Viewer
UI Automator Viewer是android-sdk自带的一个元素定位工具,非常简单好用,使用UI Automator Viewer,你可以检查一个应用的UI来查看应用的布局和组件以及相关的属性。
3.1.1. 启动uiautomatorviewer.bat
在SDK安装目录F:\android-sdk_r24.4.1-windows\android-sdk-windows\tools下
3.1.2. 连接手机
(1) 查看手机IP:设置-》系统-》关于手机-》状态消息-》IP地址 ;电脑ping手机IP可以Ping通,确保PC和手机同一网络。
(2) cmd输入adb devices,确认手机已连接上
(2) 手机打开APP,屏幕处于点亮状态
(3) 点击左上角安卓机器人按钮Devices Screenshot刷新页面
启动成功后,移动到需要定位的元素上查看属性
如有报错见4.2启动uiautomatorviewer.bat报错。
Android8.1以后sdk tools自带的uiautomator直接打开,截取不到机器界面信息
那么只能手动获取了:
1.截取uix资源文件
adb shell uiautomator dump /sdcard/screen.uix
adb pull /sdcard/screen.uix
注明:新手机地址改成:/data/local/tmp/**.uix
2.截取截图
adb shell screencap -p /sdcard/screen.png
adb pull /sdcard/screen.png
打开sdk tools目录下的uiautomatorviewer.bat,导入从机器获取的截图和资源文件
3.1.3. 代码中增加点击事件
# coding = utf-8 from appium import webdriver import time desired_caps = { 'platformName': 'Android', 'deviceName': 'KVXBB17C08202018', 'platformVersion': '7.0', 'appPackage': 'com.xx.xxx', 'appActivity': 'com.xx.activity.login.SplashActivity' } driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) time.sleep(8) driver.find_element_by_id("com.xx.xxx/close").click()
3.1.4. appium的webdriver定位方法
提供了11种元素定位方法,在selenium的基础上扩展了三个,可以在pycharm里面输入driver.find_element_by然后会自动匹配出来
3.1.5. Resource-id定位
最常用定位方法:self.driver.find_element_by_id("com.heyi.mayn.emchat:id/iv_more").click()
3.1.6. text定位
UI Automator Viewer中有些元素的resource-id属性相同,只能通过text定位。
代码中使用如下:
loc_text = 'new UiSelector().text("明星网红")' self.driver.find_element_by_android_uiautomator(loc_text).click()
1.通过text文本定位语法
new UiSelector().text("text文本")
2.文本比较长的时候,可以用textContains模糊匹配,只要文本包含匹配内容就可以了。
new UiSelector().textContains("包含text文本")
3.textStartsWith是以某个文本开头的匹配
new UiSelector().textStartsWith("以text文本开头")
4.正则匹配textMatches,这个需要配合正则表达式,就不举例了。
new UiSelector().textMatches("正则表达式")
3.3. 事件函数
3.3.1. 安装apk
import os os.system("adb install F:/pythonProjects/apk/xxxx.apk")
3.3.2. 点击事件
self.driver.find_element_by_id("com.xx.mayn.emchat:id/tv_gossip").click() # 八卦
3.3.3. 输入事件
self.driver.find_element_by_id("com.xx.mayn.emchat:id/edt_pwd").send_keys("qwe123")
3.3.4. 滑动事件
向左滑动函数 def swipe_left(self, t=500, n=1): # n滑动次数 t滑动间隔 screen_size = self.driver.get_window_size() x1 = screen_size['width']*0.75 x2 = screen_size['width']*0.25 y = screen_size['height']*0.5 for i in range(n): self.driver.swipe(x1, y, x2, y, t)
3.3.5. 弹窗权限-始终允许
# 弹窗权限-始终允许 def always_allow(self, n=1): for i in range(n): loc = ("xpath", "//*[@text='始终允许']") try: e = WebDriverWait(self.driver, 1, 0.5).until(expected_conditions.presence_of_element_located(loc)) e.click() except: pass
3.3.6. 判断元素是否存在
# 通过ID判断元素是否存在 def isElementExistById(self, resource_id): try: self.driver.find_element_by_id(resource_id) return 1 except NoSuchElementException as e: print("未找到元素:", e) return 0
3.3.7. 点击坐标定位
'''设定系数,控件在测试手机的坐标为(x_loc, y_loc),测试手机分辨率为(720,1280); 测试手机坐标/测试手机分辨率为相对系数''' def my_tap(self, x_loc, y_loc): a1 = x_loc / 720 b1 = y_loc / 1280 # 获取当前测试手机屏幕大小x,y x = self.driver.get_window_size()['width'] y = self.driver.get_window_size()['height'] # 当前手机的控件坐标为x1,y1 x1 = round(a1 * x) # 使用round取整 y1 = round(b1 * y) self.driver.tap([(x1, y1)])
3.3.8. 修改登录密码-sqlite3
账号密码本地存储,使用sqlite3
3.3.9. 结果检查
想要对结果进行检查,先判断元素是否存在;
遇到元素不存在就退出继续执行该用例;
判断元素是否存在公共函数
# 判断元素是否存在 def is_element(self, by_tag, value): ''' Determine whether elements exist Usage: is_element(By.ID, 'id/edt_pwd') ''' flag = None try: if by_tag == 'id': self.driver.find_element_by_id(value) elif by_tag == 'xpath': self.driver.find_element_by_xpath(value) flag = True except NoSuchElementException as e: print('未找到元素:', e) flag = False finally: return flag
用例中增加判断逻辑:
element = self.cc.is_element(By.ID, "com.xx.mayn.emchat:id/radio4") if element: self.driver.find_element_by_id("com.xx.mayn.emchat:id/radio4").click() # 我的 else: raise NoSuchElementException("找不到元素:我的")
3.3.10. 唤醒屏幕
3.4. Appium ios UI自动化
需要xcode支持,只能在mac上进行
4. 问题汇总
4.1. 运行python脚本,报错Could not extract PIDs from ps output. PIDS: [], Procs: ["bad pid 'uiautomator'"]
解决办法:修改Appium\node_modules\appium\node_modules\appium-adb\lib\adb.js
找到var outlines = stdout.split("\n");
在其下面添加outlines.shift();注意有分号,保存文件
重启Appium
4.2. 启动uiautomatorviewer.bat报错
Unexpected error while obtaining UI hierarchy
java.lang.reflect.InvocationTargetException
解决:
- 网上说Android高版本导致,换Android 版本低的手机试 Android 7.0可以用
- 电脑端和手机端adb版本不一致:adb shell getprop ro.build.version.sdk 查看手机SDK-api版本为28,而电脑安装的platform是21,重新下载个28版本即可搞定。(现在镜像被封了,下载不了SDK ------最后用老公的CSDN账号下载的)
3. android8.1以后sdk tools自带的uiautomator直接打开,截取不到机器界面信息
那么只能手动获取了:
1).截取uix资源文件
adb shell uiautomator dump /sdcard/screen.uix
adb pull /sdcard/screen.uix
注明:新手机地址改成:/data/local/tmp/**.uix
2).截取截图
adb shell screencap -p /sdcard/screen.png
adb pull /sdcard/screen.png
打开sdk tools目录下的uiautomatorviewer.bat,导入从机器获取的截图和资源文件
4.3. Sqlite3运行python脚本报:ImportError: DLL load failed: %1 不是有效的 Win32 应用程序。
解决方法:
Anaconda3安装目录C:\ProgramData\Anaconda3\DLLs下没有 sqlite3.dll 文件,从官网下载sqlite3.dll文件放到上面目录即可。
4.4. ModuleNotFoundError: No module named 'appium'
报错详情:ModuleNotFoundError: No module named 'appium'
解决办法:pip安装的模块pycharm还未识别到,到File-settings-Project:xx-Python Interpreter下刷新或重新添加
4.5. 启动app时清除数据
解决:desired_caps中增加参数'noReset': 'True' # 启动app时不要清除app里原有的数据