1. 环境搭建:软件安装与配置

第一次搭建Appium测试环境时,我花了整整两天时间才把所有依赖装好。后来发现,其实只要按顺序安装这几个关键组件就能避免90%的问题。先说说必须安装的软件清单:

  • JDK:建议直接安装JDK 8,这是最稳定的版本。安装完成后记得运行java -version验证,我遇到过因为系统残留旧版本导致环境混乱的情况
  • Android SDK:不用完整安装Android Studio,单独下载命令行工具就行。重点是要配置好ANDROID_HOME环境变量,这个后面会详细说
  • Python:推荐3.7+版本,太新的版本可能遇到库兼容性问题。我习惯用pyenv管理多版本Python,避免污染系统环境
  • Appium Desktop:图形化界面比命令行版更适合新手。有个坑要注意 - 安装路径不要有中文或空格,否则可能报奇怪的权限错误
  • Node.js:Appium的运行依赖Node环境。安装LTS版本即可,装完记得用npm -v检查是否成功
  • MuMu模拟器:网易官方的稳定版就行,别用修改版。安装后先别急着启动,后面有重要配置要做

环境变量是新手最容易栽跟头的地方。我建议这样配置:

  1. 用户变量里添加JAVA_HOME,指向JDK安装目录
  2. 系统Path中添加%JAVA_HOME%\bin%ANDROID_HOME%\platform-tools
  3. 新建系统变量ANDROID_HOME指向SDK目录

验证是否配对了有个妙招 - 新开cmd窗口分别执行adbjavapython这三个命令,如果都能显示帮助信息而不是"不是内部命令",说明基础环境OK了。

2. MuMu模拟器的特殊配置

MuMu模拟器默认用的adb端口是7555,这和标准模拟器不同。我第一次用时死活连不上,后来发现需要做这几个特殊操作:

首先要把MuMu安装目录下的adb.exe复制到Android SDK的platform-tools里替换原文件。这个操作很多人会忽略,结果就是adb devices永远找不到设备。替换后执行:

adb kill-server
adb connect 127.0.0.1:7555
adb devices

应该能看到类似这样的输出:

List of devices attached
127.0.0.1:7555 device

如果显示offline或者空列表,试试这些排查步骤:

  1. 确保模拟器已经完全启动(看到桌面图标)
  2. 任务管理器里结束所有adb.exe进程再重试
  3. 关闭电脑上的手机助手类软件,它们会抢占adb端口
  4. 在MuMu设置里开启USB调试模式(虽然叫USB调试,但对模拟器也有效)

有个隐藏技巧:MuMu多开时每个实例端口会递增,比如第二个实例是7556。如果要做多设备测试,需要分别连接这些端口。

3. Appium服务配置详解

打开Appium Desktop后别急着点Start Server,先做这些配置能省去后面很多麻烦:

在"Edit Configurations"里,我建议这样设置:

  • allowCors: true (解决跨域问题)
  • localTimezone: true (避免时区导致的日志时间错乱)
  • webDriverAgentUrl: http://localhost:8100 (iOS测试不用管,Android保持默认)

重点来了 - 必须勾选"Override existing sessions",否则第二次运行脚本时会报session冲突错误。这个坑我踩过三次才找到原因。

启动服务后,控制台出现"Appium REST http interface listener started on 0.0.0.0:4723"才算成功。如果端口被占用,可以在启动参数里换其他端口,但要记得后续Python脚本里的URL也要相应修改。

4. 编写第一个自动化脚本

终于到了写代码环节!先安装Python客户端库:

pip install Appium-Python-Client

这是我调试过的最简可用脚本模板:

from appium import webdriver

desired_caps = {
    'platformName': 'Android',
    'deviceName': 'MuMu',  # 自定义名称
    'platformVersion': '6.0.1',  # 需与模拟器系统版本一致
    'appPackage': 'com.android.settings',
    'appActivity': '.Settings',
    'automationName': 'uiautomator2',
    'noReset': True  # 避免每次重置模拟器
}

driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
# 点击WLAN设置
driver.find_element_by_xpath("//*[@text='WLAN']").click()
driver.quit()

几个容易出错的地方:

  1. platformVersion必须和模拟器"关于手机"里的系统版本完全一致,差个小版本号都会报错
  2. 新版本Appium推荐用uiautomator2而不是老版的UiAutomator1
  3. 元素定位优先用resource-id,其次才是text。用Android SDK里的uiautomatorviewer工具查看元素属性最可靠

5. 获取应用包名和Activity

很多教程教人用反编译工具获取包名和主Activity,其实有更简单的方法:

adb shell dumpsys window | find "mCurrentFocus"

运行后会显示类似这样的信息:

mCurrentFocus=Window{xxxxxxx u0 com.xxx.xxx/com.xxx.xxx.MainActivity}

斜杠前面是包名,后面是当前Activity。

对于未安装的应用,可以用aapt工具:

aapt dump badging your_app.apk | find "package: name="
aapt dump badging your_app.apk | find "launchable-activity: name="

6. 常见问题排查指南

问题一:adb devices列表为空

  • 解决方案:按顺序执行
    1. adb kill-server
    2. adb start-server
    3. adb connect 127.0.0.1:7555
    4. 检查模拟器设置中的"开发者选项"是否开启

问题二:Appium报错"Unable to find a matching set of capabilities"

  • 检查项:
    1. desired_caps里的键名不能有拼写错误(比如错写成'platform'少了个'Name')
    2. 确保设备名称和Appium配置一致
    3. 模拟器系统版本和caps中的platformVersion完全匹配

问题三:元素定位失败

  • 优化方案:
    1. 增加隐式等待 driver.implicitly_wait(10)
    2. 改用显式等待:
    from selenium.webdriver.support.ui import WebDriverWait
    WebDriverWait(driver, 10).until(lambda x: x.find_element_by_id("some_id"))
    
    1. 在uiautomatorviewer里确认元素是否确实存在

问题四:截图保存失败

  • 正确写法:
import os
os.makedirs('screenshots', exist_ok=True)  # 自动创建目录
driver.get_screenshot_as_file(f'screenshots/{datetime.now().strftime("%Y%m%d_%H%M%S")}.png')

7. 实战技巧:处理权限弹窗

国内应用经常在启动时请求各种权限,可以用这段代码自动点击允许:

try:
    allow_btn = driver.find_element_by_id("com.android.packageinstaller:id/permission_allow_button")
    allow_btn.click()
except:
    pass  # 如果没有弹窗就跳过

更健壮的写法是循环检测多个可能的权限弹窗:

permission_ids = [
    "com.android.packageinstaller:id/permission_allow_button",
    "android:id/button1",  # 另一种确定按钮
    "com.android.permissioncontroller:id/permission_allow_button"  # 新版Android
]

for pid in permission_ids:
    try:
        driver.find_element_by_id(pid).click()
    except:
        continue

8. 进阶:录制与回放

Appium Inspector的录制功能其实很好用,但要注意:

  1. 先启动会话再点击"Start Recording"
  2. 操作完成后别急着关会话,先点击"Copy Code"获取Python代码
  3. 生成的代码可能需要微调,特别是元素定位部分

我习惯把常用操作封装成函数:

def click_by_text(text):
    driver.find_element_by_xpath(f"//*[@text='{text}']").click()

def input_text(resource_id, text):
    elem = driver.find_element_by_id(resource_id)
    elem.clear()
    elem.send_keys(text)

最后提醒一个性能优化点:在desired_caps里加上'skipDeviceInitialization': True可以跳过一些不必要的设备检查,让脚本启动更快。这套环境搭好后,接下来就可以大展拳脚写各种自动化测试用例了。从个人经验看,环境搭建虽然麻烦,但一次配好能省去后续无数调试时间。建议把整个环境打包成虚拟机镜像或者Docker镜像,方便团队共享使用。

更多推荐