今天说说当今主流的自动化 UI 测试框架之一的 appium 使用总结,其中卡的我比较久的是被测 App 的安装时手机弹出的权限弹窗问题,主要说下解决方案。
之前也接触过网易的 airtest project,uiautomator2 等自动化测试框架, appium 相对要麻烦一些,需要很多手机设备信息,包括被测 App 的信息。
appium 主要的问题就在于它的设计就是建立在手机已经安装好了被测 App 的,它初始化连接设备需要打开指定 App,而手动去安装被测 App 时很 low 的方式,一般来说我们会想到用 脚本去点击 “同意弹窗”,但 appium 没初始化完成时是无法使用 click 方法的。
看过网上一些解决方案,说说我的实践效果:
1,采用 adb 点击弹窗 “同意” 坐标方式。
效果不佳,而且手机众多,很多手机的询问弹窗位置不一样,不建议使用。
2,通过 adb 先把被测 apk 文件 push 到手机指定文件夹,再用 db shell pm install 安装。
网上说能解决部分手机(不出现询问弹窗),但我使用的小米,华为等依然有弹窗。可能是手机原因不用吧。 多与做设备集群的自动化测试的来说,这种依然不行。
3,首次安装人工点击,测试完成后不卸载,后续 App 版本用自动化脚本测试时采取覆盖安装。
覆盖安装不会出现询问弹窗(我测的小米是这样),这种方式就只 low 一次,后续还好吧。,
4,采用其他框架如 uiautomator2 的脚本,在 appium 是初始化安装 App 时,点击掉询问弹窗。
可行,但入手门槛高。
5,下面介绍我使用的这种方案,如下:
因为 appium 需要先打开一个 App 才能完成初始化,所以我们可以在配置参数中不配置我们被测的 App,可以配置一些很小的 App 信息,且必须是每部手机上都会安装的。刚好,使用 appium 在设备与服务端通信,会在设备上安装一款叫 appium setting 的很小的 App。
因此,我们可以参数里配置它,完成初始化后,再用 adb 或者 appium 提供的安装函数去安装实际被测 App,再使用多线程去点击掉询问弹窗。代码如下:
# 配置 appium srtting 为被测 App
desired_caps = {}
desired_caps['platformName']='Android'
desired_caps['deviceName']='huawei-stf_al00-8BN0217930000453'
desired_caps['paltformVersion']='8.0.0'
desired_caps['appPackage']='io.appium.settings'
desired_caps['appActivity']='io.appium.settings.Settings'
desired_caps['autoGrantPermissions']= True
drive = webdriver.Remote('http://localhost:4723/wd/hub,desired_caps')
# 再安装真实被测 App,利用线程点击掉询问弹窗
thread1 = usb_install_thread() # 这是点击弹窗的线程
thread1.start()
drive.install_app(hGoName)
好,到此结束。喜欢的点个赞吗,谢谢大家。


未知地区 10F
哇,一下子解决了困扰我多时的问题,还有一个问题就是如何启动安装包?通过 usb 安装软件是有权限的,很多手机一般不得行
未知地区 9F
当然是用线程去点击,问题在于用线程去点击得先完成初始化,才能用 click 吧? 而 appium 配置参数里得先指定 App,打开后才算完成初始化,那么打开 App,说明已经安装上了, 实际上初始化安装 App 时,线程根本没法用 appium 的 click 操作,之前大多采用的是另外用 uiautomator 的脚本在 appium 初始化前循环检测点击,这样得启俩服务,编写 uiautomator 的脚本,有点麻烦的
未知地区 8F
跟方案 4 差不多 不过有点麻烦哦
未知地区 7F
好的 谢谢 刚开始用这个还不大会 将就看下吧 代码很简单 大家应该能看懂的
未知地区 6F
这两个是手机与服务端通信用的,这个就属于 appium 自身的需求了,可以采用上树方案 4 去用 uiautomator2 的脚本的脚本循环判断点击,但是有点麻烦,得编写人员会这两个框架,还得搭环境
未知地区 5F
class usb_install_thread(threading.Thread): # 安装确认
def init(self):
threading.Thread.init(self)
def run(self): # 把要执行的代码写到 run 函数里面 线程在创建后会直接运行 run 函数
usb_install()
def usb_install():
while True:
if flag == False:
break
try:
em = drive.find_element_by_xpath(“//android.widget.Button[contains(@text,’继续安装’)]”)
if em:
em.click()
except:
pass
try:
em =drive.find_element_by_xpath(“//android.widget.Button[contains(@text,’允许’)]”)
if em:
em.click()
except:
pass
try:
em = drive.find_element_by_xpath(“//android.widget.Button[contains(@text,’确认’)]”)
if em:
em.click()
except:
pass
这是个 python 的线程,用来判断出现 “允许”“确认” 等弹窗的,因为每个手机的可能不通,但大概就这几种,加判断就可以了
未知地区 4F
分叉 1 个线程去做了 Ui 自动化点那个。
未知地区 3F
安装 U2 之前,可以启动 U1 来解决弹窗问题,安装完成后再把 U1 关掉就完事
未知地区 2F
usb_install_thread()点击弹窗的方法实现内容是什么呢?
另外有些设备的 ROM 安装io.appium.settings和io.appium.settings.Settings两个守护进程都强制必须用户手动确认才能安装。
未知地区 1F
这思路挺赞的,上次 Jonathan 来中国参加 MTSC2018 大会的时候其实也跟恒温、恒捷和我讨论过这个问题。他们也在想办法改进这块,我给的建议是把启动 uiautomator2 的过程提前到安装 apk 之前。 你这个方法也是挺赞的,也算是独辟蹊径。不过楼主把代码格式调整下吧。。。