做移动端自动化测试,绕不开 Appium。这几年我带过不少新同事,Windows 系统上搭 python+appium 环境看着就是一路“下一步”,真轮到自己动手,坑一个接一个:JDK 版本对不上、adb 设备连不上、Appium Server 端口起不来、Python 客户端连超时,随便一个就能耗掉一下午。这篇文章我直接把踩过的坑和验证过的方案完整写出来,从零开始,在 Windows 下把 JDK、Android SDK、Appium Server、Python 客户端、设备联调全部配通,再跑通第一个冒烟脚本。适合刚入门 App 自动化测试的同学,也适合要给团队统一搭建测试环境的人做参考。
为了让这套环境不只是一个“能用”的状态,我会把每个环节为什么这么选、每一步命令在干什么、遇到报错怎么排查都讲清楚。环境搭过几轮之后你会发现,真正卡人的不是工具本身,而是不知道整条工具链的依赖关系。这篇文章的目标就是先把这个关系理顺。
1. 环境准备与整体选型思路
1.1 核心组件清单与版本建议
Windows 下做 App 自动化测试,环境从来不是“装一个软件”那么简单。先别急着下载东西,把整条链路搞清楚,后面至少省一半时间。Appium 的角色像一个“翻译官”:Python 脚本发出指令,Appium Server 接收后翻译给手机上的自动化驱动,驱动再操作 App。所以一套完整环境至少要包含下表里的这些组件:
| 组件 | 推荐版本 | 作用说明 |
|---|---|---|
| JDK | 8 或 11 | Appium Server 和部分 Android 工具的运行依赖 |
| Android SDK | platforms 33 / build-tools 33.x | 提供 adb、系统镜像、编译工具 |
| Node.js | 14 LTS 及以上 | 新版 Appium Server 的运行环境 |
| Appium Server | 2.x | 自动化测试的核心服务端 |
| uiautomator2 驱动 | 最新 | Appium 2.x 中负责 Android 平台通信的驱动 |
| Python | 3.8 及以上 | 书写测试脚本的语言 |
| Appium-Python-Client | 3.x | Python 连接 Appium Server 的客户端库 |
| Appium Inspector | 最新 | 可视化查看页面层级、定位元素的辅助工具 |
这张表里的每个组件都不是可有可无的装饰。JDK 是老牌依赖,从 Appium 1.x 时代就一直存在;到了 Appium 2.x 时代又多了 Node.js 这项运行环境要求;Android SDK 负责把 PC 和手机、模拟器连起来;Python 和客户端库则是日常写脚本的主力。哪个环节断了,后面的工作都没法展开。
1.2 版本搭配的选型逻辑
我看到不少人直接把 JDK 下到最新版,比如 19 或者 21,然后折腾一下午,各种工具要么不识别,要么报奇怪的错。说实话,在移动端自动化这个场景里,新版 JDK 带来的特性几乎用不上,反而容易因为兼容性问题浪费大量时间。所以我的建议是 JDK 直接装 8 或 11,这是经过大量实践验证的稳妥组合。网上有些项目脚本的源码甚至还是基于老 JDK 语法写的,太新的版本反而会在编译期报错。
Appium 侧的变化更值得注意。很多人还停留在 Appium 1.x 的阶段,找的教程都是去官网下载那个带图形界面的 Appium Desktop。从 2.0 开始,官方已经不再维护桌面客户端,服务端和调试工具分开独立发展。现在推荐直接用 npm 安装 Appium CLI,再通过命令安装 Android 平台驱动,环境更轻量,升级也方便,不会遇到“图形界面打不开”“服务起不来”之类的老问题。下面各章节我统一按 Appium 2.x + Python 3.8 的组合来讲,这也是目前社区里讨论最多、维护最活跃的一条路。
注意:版本选择原则是稳定和兼容优先,不是越新越好。搭环境的目的是尽快把脚本跑起来,而不是在这上面追新,这个方向别搞反。
2. 基础环境:JDK 与 Android SDK
2.1 JDK 安装与环境变量配置
第一步先装 JDK。下载安装包时选择 Windows x64 版本,安装路径建议不要带空格和中文,比如直接装到C:\Java\jdk8,后面配置环境变量会省心很多。如果电脑上装了多个 JDK,记得把 JAVA_HOME 指向你要用的那个,不要依赖系统默认的 Java 目录。
安装完之后需要配置环境变量。打开“此电脑 → 属性 → 高级系统设置 → 环境变量”,在系统变量里新建:
变量名:JAVA_HOME 变量值:C:\Java\jdk8然后在 Path 中添加一行:
%JAVA_HOME%\bin配置完成后,新开一个命令行窗口,输入java -version和javac -version,能看到版本信息就说明 JDK 装好了。这里有个细节:环境变量修改后,所有已打开的命令行窗口都不会立刻生效,必须新开窗口重新读取环境变量。很多新手卡在“明明配了,还是显示找不到 java”,十有八九就是没新开窗口。
2.2 Android SDK 的安装:commandlinetools 方式
以前装 Android SDK 会去下载 Android Studio,装一堆用不上的东西,然后还要在图形界面里点半天。其实做自动化测试只需要 SDK 的命令行工具。去 Android 开发者官网下载 commandlinetools 压缩包,解压到一个固定目录,比如C:\android-sdk。
这里有一个容易踩坑的结构问题:刚解压出来里面是cmdline-tools目录,直接能看到 bin、lib 这些子目录。官方约定的目录结构要求你必须把它整理成cmdline-tools\latest\bin\sdkmanager.bat这样的形式。实际操作时建议这样处理:在C:\android-sdk下创建cmdline-tools\latest,把解压出来的内容全部移进去。不这样做的话,后续执行 sdkmanager 会找不到自己的定位信息,直接抛错。
整理好之后,在命令行进入C:\android-sdk\cmdline-tools\latest\bin,执行以下命令安装基础组件:
sdkmanager "platform-tools" "platforms;android-33" "build-tools;33.0.0"sdkmanager是官方提供的包管理工具,可以把它理解为 SDK 的“应用商店”。这里安装的platform-tools会提供 adb 命令,platforms;android-33对应 Android 13 的平台库,build-tools则包含打包、签名等一系列工具。如果你的测试设备是 Android 12 或更低版本,装platforms;android-31甚至更低也够用,但多装一个较高版本平台库问题不大,设备侧的兼容性由 Appium 统一处理。
建议顺手执行一句:
sdkmanager --licenses把所有许可协议都接受掉。这一步不做,后面某些工具可能会因为协议未接受而拒绝初始化,报错信息还不直观。
2.3 环境变量配置细节与验证
Android SDK 装完之后,同样要在系统变量中注册:
变量名:ANDROID_HOME 变量值:C:\android-sdk然后把以下两个路径追加到 Path:
%ANDROID_HOME%\platform-tools %ANDROID_HOME%\cmdline-tools\latest\binANDROID_HOME是很多工具查找 SDK 位置的依据,ANDROID_SDK_ROOT是另一个常见变量名,建议同步设置成同一个值。某些老工具只认ANDROID_SDK_ROOT,Appium 的驱动安装和部分脚本执行时也会读取这些变量,提前配上省得后面排查半天。
验证方法很直观:新开一个命令行窗口,输入:
adb version看到类似Android Debug Bridge version 1.0.41的输出,说明 platform-tools 已生效。如果提示“adb 不是内部或外部命令”,优先检查 Path 里是否加了%ANDROID_HOME%\platform-tools,其次检查命令行窗口是否新开。到这里,Android 基础链路已经通了,接下来进入 Python 和 Appium 部分。
3. Python 与 Appium 服务端
3.1 Python 安装与虚拟环境
Python 安装本身没什么难度,但有两个点必须留意。第一,安装时勾选“Add Python to PATH”,不勾选的话后续执行 python 命令会提示找不到;第二,安装路径同样建议短一些、不带中文,例如C:\Python312。
安装完成后验证一下:
python --version pip --version两条命令都能正常输出版本信息,说明基础 Python 环境没问题。接下来我强烈建议创建一个虚拟环境,把 Appium 相关依赖都装在里面,不要直接装到系统全局。原因很实际:电脑上可能还有别的项目,每个项目对第三方库的版本要求不一样,全局安装很容易出现今天升级一个库、明天另一个项目跑不起来的情况。虚拟环境相当于给当前项目划了一个独立的“房间”。
创建和激活命令如下:
python -m venv appium_env appium_env\Scripts\activate激活后命令行前方会出现(appium_env)前缀,表示当前已进入虚拟环境。之后所有 pip 安装操作都在这环境下执行,不会污染全局。
3.2 Appium Server:从桌面版到 CLI
Appium Server 的安装是重头戏,版本关系最复杂。如果你还在按旧教程下载 Appium Desktop 的安装包,可以停下来了。从 Appium 2.0 起,官方把 GUI 客户端从服务端中剥离,不再推荐使用桌面版。现在推荐用 npm 全局安装 Appium CLI。
先确认 Node.js 已安装且版本不低于 14:
node -v npm -v然后执行:
npm install -g appium安装完成后再看版本:
appium --version如果能看到类似2.5.x的输出,说明服务端装好了。Appium 2.x 和老版本最大的区别在驱动机制:1.x 时代驱动集成在主包里,而 2.x 把驱动做成了插件式,Android 平台需要单独安装名为 uiautomator2 的驱动:
appium driver install uiautomator2这个驱动负责和手机上的自动化组件通信。没有它,启动 session 时会看到类似Could not find a driver for platformName 'Android'的报错。装完可以用appium driver list确认状态,会看到uiautomator2 - [installed]这样的标记。
最后启动服务:
appium默认监听在127.0.0.1:4723,看到日志输出listening之类的信息就说明服务正常。这个命令行窗口不要关,服务需要一直保持运行。
3.3 Python 客户端库安装
服务端就绪后,回到之前创建的虚拟环境,安装 Python 侧的客户端库:
pip install Appium-Python-Client注意正确名称是Appium-Python-Client,不是appium。有些同学在包索引里搜到别的同名包,装上后导入时报错,白白浪费不少时间。安装完成后在 Python 环境里验证:
python -c "from appium import webdriver; print('ok')"能打印 ok,说明客户端库可用。到这里,python+appium 环境的核心部分已经全部配好。接下来的问题是:怎么让它和手机建立连接、跑起第一个脚本,这才是很多教程没讲清楚的地方。
4. 设备连接与第一个脚本
4.1 真机与模拟器的连接
测试设备我建议先用模拟器,方便重置,跑自动化也不消耗真机。Android Studio 自带的 AVD Manager 可以创建模拟器:下载一个系统镜像,比如 Android 12 的 x86_64 镜像,创建虚拟设备后启动。如果不想装完整的 Android Studio,也可以单独配置模拟器,但需要手动处理系统镜像和创建命令,对新手不够友好。
模拟器启动后,在命令行执行:
adb devices正常会看到一个emulator-5554 device的设备。如果输出是unauthorized,说明设备未授权,需要在模拟器或手机上确认调试授权弹窗。如果是真机,还需要在设置里打开“开发者选项”,然后开启“USB 调试”,插上数据线后在手机弹窗里点允许。真机的 deviceName 通常是类似RF8N...的序列号,以 adb devices 显示为准。
这里有个值得注意的点:如果电脑上装了多个模拟器工具,adb 的版本可能互相干扰,导致只识别其中一个、另一个显示 offline。解决办法是统一使用 SDK 目录下的 adb,并检查系统环境变量里的路径顺序,确保%ANDROID_HOME%\platform-tools排在更靠前的位置。
4.2 用 Appium Inspector 快速定位元素
写测试脚本前,先打开 Appium Inspector。这个工具能直观展示手机界面上的元素层级和属性,定位元素时非常方便。启动后在界面里配置连接信息:
- Remote Host: 127.0.0.1
- Remote Port: 4723
- Path: /wd/hub
然后在 JSON Representation 里填上启动会话的能力参数,一个最小可用的配置如下:
{ "platformName": "Android", "automationName": "UiAutomator2", "deviceName": "emulator-5554", "appPackage": "com.android.settings", "appActivity": ".Settings", "noReset": true }这里的appPackage和appActivity表示要启动的 App。以 Android 系统设置为例,包名是com.android.settings,入口 Activity 是.Settings。点击 Start Session,如果配置没问题,Inspector 会展示出设置页面的 UI 树,鼠标点选元素就能在右侧看到它的 id、text、resource-id 等属性,这些就是写脚本时要用的定位依据。
4.3 跑通第一个冒烟脚本
有了元素信息,写第一个脚本就顺理成章了。回到虚拟环境,新建一个smoke_test.py,内容如下:
from appium import webdriver from appium.options.android import UiAutomator2Options from selenium.webdriver.common.by import By desired_caps = { "platformName": "Android", "automationName": "UiAutomator2", "deviceName": "emulator-5554", "appPackage": "com.android.settings", "appActivity": ".Settings", "noReset": True } options = UiAutomator2Options().load_capabilities(desired_caps) driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", options=options) driver.implicitly_wait(10) # 查找并点击"关于手机"入口 target = driver.find_element(By.XPATH, "//*[@text='关于手机']") target.click() # 验证跳转后的页面中出现"关于手机"标题 page_title = driver.find_element(By.XPATH, "//*[@text='关于手机']") assert page_title is not None driver.quit()脚本的逻辑很简单:启动设置 App,等待页面加载,用 XPath 找到“关于手机”并点击,最后通过断言确认跳转成功。implicitly_wait(10)给元素查找设置了最多 10 秒的隐式等待,避免设备或网络慢时频繁报错。执行命令:
python smoke_test.py如果看到页面正常拉起、控制台没有异常退出,说明 python+appium 环境真正打通了。之后要做的就是在框架里添加更多测试步骤、断言逻辑和异常处理。
5. 常见问题排查与避坑实录
5.1 高频报错速查
实战中会遇到一批非常典型的报错,我把它们整理成速查表,遇到时可以直接对号入座:
| 报错信息 | 常见原因 | 解决办法 |
|---|---|---|
Could not find a driver for platformName 'Android' | Appium 2.x 未安装 uiautomator2 驱动 | 执行appium driver install uiautomator2 |
adb: command not found | platform-tools 未安装或未加入 PATH | 检查C:\android-sdk\platform-tools是否存在,确认环境变量 |
Connection refused | Appium Server 未启动,或端口被占用 | 确认 4723 端口监听正常,必要时换端口appium -p 4724 |
Unauthorized | 设备未允许 USB 调试授权 | 在设备上重新授权,或执行adb kill-server后重连 |
SessionNotCreatedException | capabilities 中 deviceName 与 adb 显示不一致 | 将 deviceName 改成adb devices输出的实际值 |
Error: Could not find adb in SDK | ANDROID_HOME 指向错误或 SDK 目录不完整 | 重新配置 ANDROID_HOME,再执行 sdkmanager 安装 platform-tools |
| 脚本执行时中文乱码 | Windows 命令行默认编码不是 UTF-8 | 执行chcp 65001切换代码页,脚本文件统一用 UTF-8 保存 |
比如connection refused,很多时候不是服务没起,而是同时装了多个 Node 版本,Appium CLI 装在了其中一个 Node 的全局目录下,新开的命令行窗口加载的是另一个。这类问题的排查思路很关键:先从环境变量入手,确认命令行实际执行的命令来自哪个路径,再顺藤摸瓜。
5.2 环境搭建的几条避坑经验
最后分享几条实操中沉淀下来的经验,这些在官方文档里往往不会写明。
第一,Appium 服务端和测试脚本要有一个明确的启动顺序:先启动模拟器或连接真机,再启动 Appium Server,最后执行脚本。反过来容易遇到连接超时,而且排查起来费劲。如果你经常跑自动化,可以把这几条命令串成一个启动脚本,一键做完设备检测、服务启动和自测。
第二,不要忽视端口冲突。4723 是 Appium 默认端口,5037 是 adb 端口。某些软件可能占用这些端口。一条很管用的排查命令是:
netstat -ano | findstr 4723能看到占用进程的 PID,然后去任务管理器里按 PID 找到对应进程,决定是否结束它。
第三,虚拟环境这个习惯一定要养成。我之前在团队里观察过,有人在全局环境里装了新版 Appium-Python-Client,结果另一个项目用的老版测试框架导入同名模块时报了一堆错。后来统一改用虚拟环境管理依赖,这类问题就再也没出现过。
第四,团队协作时建议把环境版本写成固定配置文件。我的做法是创建一个requirements.txt,里面锁定 Appium-Python-Client 的版本号;Node 侧的 Appium 版本和驱动版本也在文档里登记。这样无论是换电脑还是新同事入职,照着版本号安装,半小时内就能恢复一套一致的环境,不会出现“我这边能跑,你那边不行”的情况。
第五,定位元素时优先用 resource-id 或 text,XPath 能用但别滥用。整个环境搭好后,后续真正的工作就落在元素定位和脚本维护上。Inspector 看层级时,优先选稳定的属性作为定位锚点,页面改版时脚本也能少改几行。
我个人在实际操作中最深的体会有两点。一是这套环境本质上就是一条工具链,每一环都有明确职责,理解了链路关系,报错时脑子里自然就有排查方向。二是别怕重装,环境搭坏了大不了删掉重来,Windows 下路径问题很多时候重装一次比反复排查更快。希望这篇文章能帮你顺利跑通第一个 Appium 脚本,后面做数据驱动、关键字驱动框架时,也就有个踏实的底子。