You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Appium单测试后ADB连接失败、启动超时问题求助

嗨,我来帮你梳理下这个问题的核心和解决办法——我之前也碰到过类似UiAutomator2和noReset搭配的坑,咱们一步步来拆解:

核心问题分析

你遇到的问题本质是**noReset=True配置和driver.reset()调用的冲突,导致Appium UiAutomator2依赖的Appium Settings应用状态异常**,进而让ADB的am start -W命令无法捕获应用启动完成的系统信号:

  • noReset=True是告诉Appium保留被测应用的缓存和用户数据,不要重置状态;
  • 但你调用了driver.reset(),这个方法会强制清除被测应用数据并重启,两个操作本身就逻辑矛盾;
  • 更关键的是,UiAutomator2的核心服务依赖Appium Settings应用,当这两个冲突操作触发后,Appium Settings的状态会和被测应用绑定混乱,导致后续ADB启动应用时,系统无法正常返回启动完成的回调,所以am start -W会一直挂起等待,最终触发超时。

另外还有个容易忽略的小细节:你的desired_capabilities里noReset用的是字符串'true',但Appium期望的是布尔值True,这个解析异常可能加剧了状态混乱的问题。

解决方案

1. 先修复desired_capabilities的基础配置

把'noReset': 'true'改成布尔值True,同时调大ADB超时时间留足处理空间:

desired_capabilities = {
    'platformName': 'Android',
    'platformVersion': '8.0',
    'deviceName': 'WVGA_API_26',
    'avd': 'WVGA_API_26',
    'app_package': 'com.ferly.ferly',
    'app_activity': 'host.exp.exponent.experience.ShellAppActivity',
    'app_wait_package': 'com.ferly.ferly',
    'automationName': 'UiAutomator2',
    'noReset': True,  # 修正为布尔值
    'adbExecTimeout': 30000  # 超时时间调整为30秒
}

2. 替换driver.reset()的实现,避免逻辑冲突

既然用了noReset=True,就不要用Appium自带的driver.reset(),而是用ADB命令手动重启应用,既保留应用数据,又能实现重启需求:

def restart_app(driver):
    app_package = driver.capabilities['appPackage']
    app_activity = driver.capabilities['appActivity']
    
    # 强制停止应用
    driver.execute_script('mobile: shell', {'command': f'am force-stop {app_package}'})
    # 启动应用(不用-W参数,避免等待超时)
    driver.execute_script('mobile: shell', {'command': f'am start -n {app_package}/{app_activity}'})

之后测试里需要重启应用的地方,调用这个方法即可。

3. 永久解决状态异常:清理Appium Settings状态

不用每次卸载Appium Settings,只需要清除它的缓存数据就能恢复状态,建议在测试结束后(不管成功失败)添加这个清理步骤:

def clean_appium_settings(driver):
    # 清除Appium Settings的缓存和数据
    driver.execute_script('mobile: shell', {'command': 'pm clear io.appium.settings'})

如果担心初始化driver前状态异常,也可以提前用ADB命令检查并清理:

import subprocess

def pre_check_device(device_id):
    # 检查Appium Settings是否存在
    result = subprocess.run(
        f'adb -s {device_id} shell pm list packages io.appium.settings',
        capture_output=True,
        text=True
    )
    if 'io.appium.settings' not in result.stdout:
        # Appium启动时会自动安装,这里无需手动操作
        pass
    # 强制清除缓存
    subprocess.run(
        f'adb -s {device_id} shell pm clear io.appium.settings',
        check=True
    )

4. 模拟器专属方案:用快照恢复状态

因为你用的是模拟器,可以创建一个干净的初始快照,每次测试前恢复快照,彻底避免状态积累的问题:

import subprocess

def restore_emulator_snapshot(avd_name):
    # 关闭当前运行的模拟器
    subprocess.run(f'adb -s emulator-5556 emu kill', capture_output=True)
    # 启动模拟器并恢复默认快照
    subprocess.run(f'emulator -avd {avd_name} -no-boot-anim -snapshot default', check=True)

这个方法适合稳定的测试环境,每次测试都从干净状态开始,一劳永逸。

验证方法

修改后先手动执行ADB命令测试:

adb -P 5037 -s emulator-5556 shell am start -W -n com.ferly.ferly/host.exp.exponent.experience.ShellAppActivity -S

如果能正常输出Complete,说明状态已经恢复,再跑Appium测试就不会超时了。

内容的提问来源于stack exchange,提问作者Surilan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:30:47