「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。
APPIUM环境搭建
首选python变成语言+appium依赖库+Appium-python-Client客户端
- Java JDK必不可少
- Android-SDK
- Nodejs环境(因为appium客户端是node开发的)
npm install -g appium
-
- 在上面appium报错的时候,根据提示安装对应的版本:.net framework 4.5
- APPIUM服务端
(appium) C:\Users\qguan>appium
[Appium] Welcome to Appium v1.18.0
[Appium] Appium REST http interface listener started on 0.0.0.0:4723
- python安装appium客户端
pip install Appium-python-Client
- 下载夜神模拟器,Android版本比较高,可能一些公司会抛弃低版本的Android客户端
# 夜神模拟器,在bin目录下将nox_adb重命名,或者将SDK的adb.exe覆盖到夜神bin目录下
夜神端口默认:62001
逍遥端口默认:21503
注意事项
时常在使用模拟器或真机做自动化的时候,会出现异常报错:找不到设备,经确认adb devices是有检测到的;也能adb connect连接正确,就是会突然找不到。
执行脚本时,注意:先启动appium服务器,否则会连接不到服务器找不到设备;然后需要connect连接模拟器;执行完之后,建议进行关闭操作。
Python代码示例
参考bat示例,先清楚要做什么再做什么,但是在Python中,可能需要稍微调整一下执行顺序,找到或拼接apk的绝对路径先存起来,然后再依次遍历,对于appium工具会有所不同,这是bat所不具备的,需要设置(模拟器或真机)设备和app的参数属性,然后再创建远程连接对象,启动app和卸载,然后再启动后还可以进行app功能点击事件。
- desired_caps属性
caps = {}
caps["platformName"] = "Android"
caps["platformVersion"] = "9" # 这个很重要,测试设备的Android版本号
caps["deviceName"] = "127.0.0.1:4723" # 模拟器有各自的默认端口,而真机的默认端口是从4723递增的
# selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: 'app' option is required for reinstall
caps["app"] = None # apk包路径,在设备没有时,会自动安装
caps["appPackage"] = "com.chutzpah.yasibro" # 应用包名,可以用来检查设备已安装
caps["appActivity"] = "com.chutzpah.yasibro.main.view.MainActivity"
caps["automationName"] = "UIAutomator2"
caps["resetKeyboard"] = True
caps["unicodeKeyboard"] = True
caps["noReset"] = True # 表示默认app原有的数据,如果是每次安装则无效False
- 找到apk包并存储绝对路径
# 拼接apk包路径
BASEDIR = os.path.dirname(os.path.dirname(__file__))
APKPATH = os.path.join(BASEDIR, "10.40.0")
# 遍历获取apk绝对路径
APKFILES = []
for root, _, files in os.walk(APKPATH):
for file in files:
APKFILES.append(os.path.join(root, file))
- 启动appium后台服务并创建adb连接设备
# 启动appium服务
subprocess.call("start /b appium", shell=True)
# 连接设备
os.popen("adb connect {}".format(caps["deviceName"]))
- 执行app对应操作之后 ,应关闭appium服务并断开adb连接
def stop_appium(port=4723):
"""释放指定的端口"""
cmd_find = 'netstat -aon | findstr %s' % port
result = os.popen(cmd_find).read().split()[-1]
if result:
cmd_kill = 'taskkill -f -pid %s' % result
os.popen(cmd_kill)
# 关闭服务
stop_appium()
# 设备断开连接
os.popen("adb disconnect {}".format(caps["deviceName"]))
- app的操作流程就是遍历apk包,然后创建连接对象,最后卸载
# 遍历apk路径,依次启动-卸载-再启动
for APKFILE in APKFILES:
caps["app"] = APKFILE
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", caps)
# 这个中间部分,可以实现app部分功能操作,以便真实达到生产apk包的走查效果
INSTALLED = driver.is_app_installed(caps["appPackage"])
if not INSTALLED: # 这段代码块基本不会执行
driver.install_app(APKFILE)
print("需要安装")
else:
driver.remove_app(caps["appPackage"])
print("卸载APP")
sleep(2)
driver.quit()
- 进入SDK\tools\bin目录下双击uiautomatorviewer就可以对app的界面进行元素查找
总结
整个代码部分和环境部署环节,最难的估计就是环境搭建了,因为它不同的设备(虚拟、真机)从连接和设置上都有很大区别,有些不一定都适用,所以才很难调试。但是苦心人天不负,最终还是被题主调试出来了,然后对于这些操作都需要去思考的,题主原本搭建的框架,再从头看代码都有些不知所以,当初是怎么写的、怎么实现的,为啥过了一段时间不维护它就不行呢?