appium+python自动化47-首次打开app权限弹窗问题

前言

用真机运行appium代码,首次打开app有的手机会出现权限弹窗问题,一般这种弹窗都是在引导页前面或者引导页后面出现。权限弹窗上面的按钮都是固定的,
只需要定位到“始终允许”按钮,点击确定就可以了。还有一个问题是这种弹窗的个数不确定,有的app是2个有的是3个,为了解决这个问题,可以专门写个判断方法。
注意:模拟器是不会有这种权限弹窗的

环境:
appium 1.8
android 7.0
美团app

权限弹窗

1.以美团app为案例,安装app首次启动的时候,在引导页出现权限弹出框,如下图这种

1070438-20180515171447043-1699338308.png

2.这种弹窗是可以直接定位到的,这里不能通过id去定位了,因为弹窗比较多,每次id都不太一样,但是文本text都是一样的:始终允许

1070438-20180515172205137-916898618.png

定位系统弹窗

1.通过xpath来定位按钮:始终允许

loc = ("xpath", "//*[@text='始终允许']")

2.用selenium里面的显示等待模块(WebDriverWait)和判断模块(expected_conditions)封装定位方法,之前selenium教程里面详细讲过,这里就不重复写了

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 判断是否有权限弹窗
for i in range(5):
    loc = ("xpath", "//*[@text='始终允许']")
    try:
        e = WebDriverWait(driver, 1, 0.5).until(EC.presence_of_element_located(loc))
        e.click()
    except:
        pass

3.写个单独的函数,封装下判断系统权限弹窗,在之前用例前调用一次就可以了

1070438-20180515181134286-359460131.png

参考代码

# coding:utf-8
from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os
import time

# 作者:上海-悠悠 QQ交流群:512200893

PATH = lambda x: os.path.join(os.path.dirname(os.path.realpath(__file__)), x)

# 百度下载一个美团app,放当前脚本同一目录
print(PATH('meituan_626.apk'))


desired_caps = {
                'platformName': 'Android',
                'deviceName': '127.0.0.1:62001',
                'platformVersion': '7.0',
                'app': PATH('meituan_626.apk'),
                'appPackage': 'com.sankuai.meituan',
                'appActivity': 'com.meituan.android.pt.homepage.activity.Welcome',
                'noReset': 'true',
                # 'resetKeyboard': 'true',
                # 'unicodeKeyboard': 'true'
                }
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)

time.sleep(3)

def always_allow(driver, number=5):
    '''
    作者:上海-悠悠 QQ交流群:512200893
    fuction:权限弹窗-始终允许
    args:1.传driver
    2.number,判断弹窗次数,默认给5次
    其它:
    WebDriverWait里面0.5s判断一次是否有弹窗,1s超时
    '''
    for i in range(number):
        loc = ("xpath", "//*[@text='始终允许']")
        try:
            e = WebDriverWait(driver, 1, 0.5).until(EC.presence_of_element_located(loc))
            e.click()
        except:
            pass

if __name__ == "__main__":
    # 调用始终允许函数
    always_allow(driver)

在学习过程中有遇到疑问的,可以appium+python QQ群交流:330467341

<think>好的,用户问的是关于App自动化测试中处理真机系统弹窗的方法。这个问题挺常见的,特别是在进行移动自动化测试的时候,系统弹窗比如权限请求、地理位置提示或者系统更新通知,这些都会干扰测试流程,导致脚本失败。我得先回忆一下常见的处理方法。 首先,可能需要考虑不同的自动化工具,比如Appium,因为大部分App自动化测试都是基于它。不同的工具可能有不同的处理方式,但核心思路应该类似。比如,Appium提供了处理弹窗的方法,比如使用switch_to.alert来处理,但系统弹窗和应用内弹窗可能不同,系统级别的弹窗可能不在应用上下文里,所以可能需要其他方式。 然后,系统弹窗的处理可能涉及到权限设置。比如在启动App的时候预先设置好所需的权限,避免测试过程中弹出权限请求。这可以通过desired capabilities来配置,比如autoGrantPermissions参数,让Appium自动处理权限弹窗。不过这可能只适用于部分情况,不是所有系统弹窗都能这样处理。 另外,可能需要使用ADB命令来模拟点击。因为系统弹窗属于系统UI,普通的自动化工具可能无法直接识别,这时候通过ADB发送按键事件,比如按回车或者点击坐标位置,可能可以关闭弹窗。不过这种方法依赖于设备的具体弹窗样式和按钮位置,可能不够稳定,尤其是不同厂商的定制系统可能弹窗位置不同。 还有一种情况是弹窗出现的不确定性,这时候可能需要异常处理机制。比如在每次操作后检查是否有弹窗出现,如果有就处理掉。或者设置一个定时任务,定期检查并关闭弹窗。这种方法可能需要结合自动化工具的弹窗检测功能和重试机制。 还有,有些弹窗可能只在特定条件下出现,比如首次启动时的权限请求,或者系统更新提示。针对这种情况,可以在测试前通过ADB预先设置好权限,或者禁用自动更新,从而避免弹窗出现。这属于测试环境配置的一部分,可能需要在测试初始化阶段完成。 不过,用户可能更想知道具体的操作步骤,比如在Appium中如何处理,或者如何用ADB命令处理。需要分步骤说明,可能包括代码示例或者命令示例,这样用户更容易理解和实施。 同时,需要注意不同的操作系统版本和设备型号可能会有不同的弹窗行为,可能需要针对不同的情况提供不同的解决方案。比如在Android高版本中,权限管理更严格,可能需要不同的处理方式,而iOS可能又有所不同,但用户的问题没有指定平台,可能需要涵盖Android和iOS,但通常情况下,系统弹窗处理在Android上更为常见,因为iOS的自动化测试可能限制更多。 总结一下,处理系统弹窗的方法大概有几种:预配置权限、使用自动化工具的内置方法、ADB命令模拟操作、异常处理结合重试机制。需要逐一解释这些方法,并给出具体的例子,比如Appium的代码片段或者ADB命令示例。此外,可能还需要提到第三方工具如AirTest的图像识别功能,如果弹窗无法通过元素定位的话,可以用图像识别点击指定位置。 另外,需要注意真机测试时,可能无法完全避免某些系统弹窗,比如低电量提示或者来电,这时候可能需要测试环境的管理,比如保证电量充足,使用免打扰模式等。这也是处理系统弹窗的一部分,属于环境配置的优化。 最后,可能需要比较不同方法的优缺点,比如预配置权限的方法可靠但可能不全面,ADB命令可能不够稳定但适用范围广,而图像识别可能更灵活但依赖设备分辨率等。用户可以根据具体情况选择合适的方法,或者结合多种方法提高稳定性。</think>在App自动化测试中,处理真机系统弹窗(如权限请求、GPS提示、系统升级弹窗等)是常见难点。以下是分步解决方案和核心方法: --- ### 一、弹窗类型识别 1. **系统级弹窗** - 由操作系统触发(如Android/iOS权限弹窗、系统更新提示) - **特点**:脱离App上下文,无法通过普通UI定位工具直接捕获 2. **应用级弹窗** - 由被测App自身触发(如登录提示、广告弹窗- **特点**:可通过UI元素定位工具(如Appium Inspector)识别 --- ### 二、系统弹窗处理方案 #### 方案1:预配置设备权限(推荐) 通过自动化脚本启动前**预先授予权限**,避免弹窗出现: ```python # Appium desired_capabilities 配置示例 desired_caps = { "autoGrantPermissions": True, # 自动处理Android权限弹窗 "autoAcceptAlerts": True # 自动处理iOS弹窗(仅部分框架支持) } ``` #### 方案2:ADB命令操作(Android专属) 通过ADB模拟点击/按键事件关闭弹窗: ```bash # 允许某项权限(需替换具体权限名) adb shell pm grant <package_name> <permission> # 模拟物理返回键关闭弹窗 adb shell input keyevent KEYCODE_BACK # 点击屏幕坐标(需提前获取弹窗按钮位置) adb shell input tap x y ``` #### 方案3:自动化框架内置方法 使用Appium的`switch_to.alert`处理弹窗(**仅适用应用级弹窗**): ```python # 检查弹窗是否存在 alert = driver.switch_to.alert if alert.text.contains("允许"): alert.accept() # 点击确认 else: alert.dismiss() # 点击取消 ``` #### 方案4:图像识别技术(通用但成本高) 使用OpenCV/Airtest等工具识别弹窗按钮位置: ```python # Airtest示例:通过截图匹配并点击"允许"按钮 touch(Template("allow_button.png")) ``` --- ### 三、特殊场景处理 1. **iOS弹窗处理** - 使用[WebDriverAgent的弹窗API](https://github.com/appium/appium-xcuitest-driver#mobile-handlepermissionalert) - 部分框架需依赖`mobile: acceptAlert`扩展命令 2. **动态弹窗定位** ```python # 重试机制 + 异常捕获 from selenium.common.exceptions import NoAlertPresentException def handle_alert(retries=3): for _ in range(retries): try: alert = driver.switch_to.alert alert.accept() break except NoAlertPresentException: time.sleep(1) ``` --- ### 四、最佳实践 1. **测试前环境准备** - 关闭系统自动更新 - 禁用非必要系统通知(通过ADB/开发者选项) - 保持设备电量充足 2. **弹窗白名单机制** 记录测试过程中遇到的弹窗类型,建立自动化处理规则库 3. **跨平台兼容方案** ```python if platform == "Android": adb_handle_alert() elif platform == "iOS": driver.execute_script('mobile: acceptAlert') ``` --- ### 五、工具链推荐 | 工具/技术 | 适用场景 | 缺点 | |-----------------|--------------------------|-----------------------| | Appium + ADB | Android系统级弹窗 | 需适配不同设备分辨率 | | WebDriverAgent | iOS系统弹窗 | 对Xcode版本有依赖 | | Airtest | 图像识别类弹窗 | 维护截图成本高 | | UiAutomator2 | Android深层系统交互 | 需要ADB调试权限 | --- 通过组合预配置、ADB命令和异常重试机制,可覆盖90%以上的系统弹窗场景。建议优先通过设备预配置减少弹窗触发,对不可避弹窗采用ADB+自动化框架的混合策略。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值