Appium appium+python 解决安装权限弹窗

A308寝帅 · 2018年09月08日 · 最后由 hope1 回复于 2022年12月12日 · 6715 次阅读

今天说说当今主流的自动化 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)

好,到此结束。喜欢的点个赞吗,谢谢大家。

共收到 42 条回复 时间 点赞

看起来不错,赞一个~

Sutune 回复

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 的线程,用来判断出现 “允许”“确认” 等弹窗的,因为每个手机的可能不通,但大概就这几种,加判断就可以了

desired_caps2 = {"deviceName":"860BCMN22FF2",
                "app": app,
                "noReset": True,
                "appWaitPackage": "c.l.a",
                "appWaitActivity":"com.example.TestPlugin.MyActivity",
                "appWaitDuration": 60000,
                "newCommandTimeout": 200,
                "platformVersion": "7.0",
                "autoGrantPermissions": True,
                "platformName": "Android",
                "automationName": "UiAutomator2"
                }


sleep(3)


if __name__ == "__main__":
    # 调用始终允许函数
    print('begin main')

    # performance_service = PermissionServer(desired_caps['deviceName'], False)
    # performance_service.start()

    driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
    time.sleep(1)
    # performance_service.setPause(1)


遇见几个问题:已经 block 了

  1. 为什么后安装上的 app, 启动后不长时间就自己杀死进程呢??
  2. 发现安装上的 app 和原来的 app 签名文件不一样? 如何解决这个 2 个问题呢???

app 升级到 28 后,必须怎么解决的???

安装 U2 之前,可以启动 U1 来解决弹窗问题,安装完成后再把 U1 关掉就完事

分叉 1 个线程去做了 Ui 自动化点那个。

Sutune 回复

这两个是手机与服务端通信用的,这个就属于 appium 自身的需求了,可以采用上树方案 4 去用 uiautomator2 的脚本的脚本循环判断点击,但是有点麻烦,得编写人员会这两个框架,还得搭环境

李海默 回复

跟方案 4 差不多 不过有点麻烦哦

好的 谢谢 刚开始用这个还不大会 将就看下吧 代码很简单 大家应该能看懂的

陈子昂 回复

当然是用线程去点击,问题在于用线程去点击得先完成初始化,才能用 click 吧? 而 appium 配置参数里得先指定 App,打开后才算完成初始化,那么打开 App,说明已经安装上了, 实际上初始化安装 App 时,线程根本没法用 appium 的 click 操作,之前大多采用的是另外用 uiautomator 的脚本在 appium 初始化前循环检测点击,这样得启俩服务,编写 uiautomator 的脚本,有点麻烦的

哇,一下子解决了困扰我多时的问题,还有一个问题就是如何启动安装包?通过 usb 安装软件是有权限的,很多手机一般不得行

还有我要测多部手机,手机信息可以从数据库中读到,那可以配置 Appnium 自动安装软件给权限吗?同一个软件安装包在不同手机上名称会变吗

红客联盟 回复

如何启动安装包?不论你的安装包在手机还是电脑都可以用 adb 命令去安装,usb 安装权限问题,我这篇文章就是解决这个的, appium 不能配置自动给软件安装权限,权限是系统的, 同一个安装包在不同手机上包名是一样的

A308寝帅 回复

那这个有点麻烦的就是有的厂商的手机,对 USB 启动安装限制很严,通过 usb 不能自动安装,比如 vivo

红客联盟 回复

我文章中讲了如何解决这个安装权限问题的,uiautomator 的话直接写个线程,循环检查就 ok,线程代码也在评论区给了,appium 有点不同,解决方案自己看文章吧,很详细了

A308寝帅 关于 USB 安装安卓软件权限问题 中提及了此贴 09月10日 11:43
A308寝帅 Appium 安装、启动 app 权限弹框问题 中提及了此贴 09月10日 11:45
A308寝帅 回复

您的文章认真拜读了,您说的权限是安装软件启动后需要获取的权限,我的意思是很多厂商直接限制了安装包的启动,也就是通过 usb 根本无法启动安装软件,自然也就没有后续的权限弹框选择

红客联盟 回复

我说的是安装软件时的权限(安装时手机弹窗 “是否允许安装,不是从应用市场下载的。。。等等警告,需要人工确认”),不是安装后首次启动的权限,usb 怎么会无法安装呢?安卓手机不像 iOS 吧,是允许用户自己安装软件的,只不过是要出现 警告/确认弹窗的

红客联盟 回复

对 您也可以使用 appium 的 安装函数去安装试试,我这边都可以哎,只是弹窗问题解决就行了

mark 一下,感谢分享

提示找不到这个软件包

能够不用 appnium 框架,只进行 ui 点击操作手机端权限吗

红客联盟 回复

用 UI2 来做自动化脚本也可以啊 ,其实个人感觉 UI2 更简单,UI2 连接设备只需要 device 号,连接后用的多线程点击也可以的,UI2 的框架如何使用可以去官方学习下

红客联盟 回复

你用 adb 安装怎么会找不到呢?adb 安装好像有 3 种还是 4 种方式呢,你可以直接从电脑里安装到手机啊
os.system("adb install -r " + hGoName) gGoName 是 apk 文件在电脑的地址,这只是一种方式哈,当然,很多手机会有弹窗的

A308寝帅 回复

我是说 appnium 安装找不到你哪个包

用 UI2 开启多线程前几次还可以 click 到按钮,后边就 click 不到了哇,线程学你的做了判断和异常处理的

if flag == False:
break
这个 flag 标志位是依据什么设置的呢,大佬

红客联盟 回复

我这个线程不是只为了点一部手机,是为了点掉多不手机的弹窗,而多部手机的弹窗文字都不一样,所以做了判断,判断有就点,没有就下一个判断,异常处理是有时候没点到不至于脚本报错(有的手机会有弹窗时间,10 秒内不点就消失,有时候会错过)。

红客联盟 回复

if flag == False:
break 这是个开关,在脚本开头 你要先写句 flag = Ture , 这时线程会循环判断 有没有方法里写的那几个弹窗, 当你觉得脚本某阶段不需要线程点击了(安装完成),你就写句 flag = False 线程循环检测到 flag = False 时 ,就停止了

A308寝帅 回复

这个原理我知道,我只是想了解一下你那边是如何判断脚本不需要点击了的,这个很关键

红客联盟 回复

这个你可以一直监控到你进入 App,根据情况来使用吧,安装这块的线程你就可以当进入 App 后就关闭掉

解决了一个顽疾啊,有时间自己试试。
还有一个问题,想问下,用 python 的 os 安装包的时候,adb 每执行一次,感觉下次执行还是需要初始化,之前用 airtest 的时候,多次调用单个的 adb 命令会出问题
比如说我清除包的数据(模拟了次卸包重装),做了一件事,之后再掉接口去安装一个渠道包,这个时候它就超时了,看后台一堆 5037 的进程,
想问问有什么办法能像在命令台一样,只要连接没断开,下次可以直接执行 adb 命令呢

整个 service 去弄这些事情也是不错的

这个怎么在 robotframework 实现呢?

A308寝帅 回复

请问是安装 apk 和安装确认一起进行是吗?

李海默 回复

哈哈,我就打算这么处理

楼主你好,我用你的方法也是无法定位,最终的结果是安装超时报错。在 appium server 那里查看信息输出,发现定位回来的结果是空的。

楼主,用你的方法尝试了下,确实很好,但是有一点,有的手机偶尔执行安装的时候,那个安装弹窗一直不出来,然后另一个线程就开始不停的查找安装权限弹窗了,怎么安装弹窗出不来安装不上是为什么呢

appium driver 的安装弹框元素查找比较慢,我实测发现经常还没查到弹框按钮,安装就等待超时了。

xxL 回复

呃呃 这个问题我还没遇到过呢 我这边多次调用 adb 命令没问题的 你检查下你的版本这些 用最新的试试吧 我没遇到过这个问题哦

ios 需要授信应用,怎么解决

这思路挺赞的,上次 Jonathan 来中国参加 MTSC2018 大会的时候其实也跟恒温、恒捷和我讨论过这个问题。他们也在想办法改进这块,我给的建议是把启动 uiautomator2 的过程提前到安装 apk 之前。 你这个方法也是挺赞的,也算是独辟蹊径。不过楼主把代码格式调整下吧。。。

usb_install_thread()点击弹窗的方法实现内容是什么呢?
另外有些设备的 ROM 安装io.appium.settingsio.appium.settings.Settings两个守护进程都强制必须用户手动确认才能安装。😅

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册