1. 项目概述:为什么WDA是iOS自动化测试的基石
如果你正在或打算涉足iOS应用的自动化测试,那么WebDriverAgent(WDA)这个名字你一定绕不过去。它不是一个简单的工具,而是整个iOS自动化测试生态的底层协议实现者和核心驱动引擎。简单来说,Appium、Macaca这些我们耳熟能详的跨平台自动化测试框架,在iOS端最终都要依赖WDA去和手机上的应用“对话”。没有WDA,iOS自动化测试就无从谈起。所以,无论你是测试工程师、开发工程师还是对质量保障感兴趣的技术爱好者,亲手从零配置一遍WDA,理解其工作原理和配置过程中的“坑”,都是构建你iOS自动化知识体系中最扎实、最关键的一步。
这个过程听起来可能有些复杂,涉及到Xcode、开发者证书、真机等一系列苹果生态特有的概念。网上教程很多,但往往因为环境差异、苹果政策更新而失效,导致新手在配置时频频碰壁,从入门到放弃。这篇文章的目的,就是以一个踩过无数坑的过来人身份,带你手把手、无死角地完成WDA的配置。我会把每一步的原理、可能遇到的问题以及背后的“苹果逻辑”都讲清楚,让你不仅能把环境搭起来,更能理解为什么要这么做。当你成功运行起第一个WDA测试时,你对iOS自动化测试的理解将不再浮于表面。
2. 环境准备与核心概念解析
2.1 硬件与软件清单:你的“手术台”和“手术刀”
在开始“手术”前,我们必须清点好所有工具。这是保证后续流程顺畅的基础,很多失败案例都源于前期准备不足。
硬件要求:
- 一台Mac电脑:这是铁律。因为WDA的编译、签名和安装依赖于Xcode,而Xcode是macOS独占的。试图在Windows或Linux上直接搞WDA是徒劳的。虚拟机方案(如VMware安装macOS)理论上可行,但涉及驱动、USB直通和性能问题,极其不稳定,不推荐用于生产或学习。
- 一部iOS真机:模拟器(Simulator)也可以运行WDA,但真机测试才是最终目的。真机测试涉及开发者证书和签名,是配置的核心难点。手机系统版本建议在iOS 12及以上,太老的系统可能缺少WDA所需的某些框架支持。确保手机电量充足,并准备一根原装或MFi认证的优质数据线,劣质线缆会导致连接不稳定,这是排查问题时最容易被忽略的细节。
软件要求:
- Xcode:从Mac App Store下载安装最新稳定版即可。这是苹果官方的集成开发环境,我们用它来编译WDA工程并管理证书。安装后,第一次启动需要同意许可协议,并完成一些初始组件安装(Command Line Tools)。务必完成这一步。
- Homebrew:macOS的包管理器,我们用它来安装一些必要的命令行工具。打开终端(Terminal),执行以下命令安装(如果已安装请跳过):
/bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)” - 依赖工具:通过Homebrew安装
libimobiledevice和carthage。brew install libimobiledevice brew install carthage- libimobiledevice:这是一套跨平台库,用于和iOS设备通信。我们主要用其中的
idevice_id命令来获取设备的UDID,用ideviceinstaller安装应用。它比Xcode的命令行工具更轻量、更通用。 - carthage:一个去中心化的依赖管理工具。WDA项目使用它来管理第三方库(如
RoutingHTTPServer)。我们需要用它来拉取和编译这些依赖。
- libimobiledevice:这是一套跨平台库,用于和iOS设备通信。我们主要用其中的
注意:网络环境是安装这些工具时最大的变数。Homebrew和carthage的源都在国外,如果下载缓慢或失败,需要为Homebrew和carthage配置国内镜像源,这是一个非常常见的预处理步骤。
2.2 理解核心概念:证书、描述文件与签名
这是iOS开发/测试特有的,也是最让人头疼的部分。你可以把它想象成一套“门禁系统”。
- Apple ID与开发者账号:你的身份标识。一个免费的Apple ID就可以进行真机调试,但有设备数量(最多3台)和功能限制(如无法使用推送通知)。付费的Apple Developer Program(年费99美元)则解锁全部功能,适合团队和上架发布。
- 证书(Certificate):由苹果颁发的、安装在Mac上的“电子身份证”。它证明了“你是谁”。分为开发证书(Development)和发布证书(Distribution)。我们做自动化测试,使用开发证书即可。证书通过Keychain Access(钥匙串访问)应用管理。
- 标识符(Identifier):即App ID,是你应用的唯一反向域名标识符,如
com.yourcompany.WebDriverAgentRunner。它指明了这个证书和描述文件是给哪个应用用的。 - 设备(Device):你需要将测试设备的UDID添加到你的开发者账号下,苹果才允许你安装开发版应用到这台设备。
- 描述文件(Provisioning Profile):这是一个将证书、App ID和设备绑定在一起的配置文件。它被嵌入到应用包(.ipa)中。当iOS设备安装应用时,系统会检查描述文件:证书是否有效?App ID是否匹配?设备是否在允许列表内?全部通过,应用才能运行。
对于WDA,我们需要两个东西:
- 一个开发证书:用来签名。
- 一个包含你测试设备UDID的开发描述文件:让WDA能安装到你的真机上。
Xcode可以自动帮我们管理这些(即所谓的“自动签名”),但对于WDA这种特殊项目,自动签名经常失灵。因此,掌握手动配置是更可靠的技能。
3. 获取与配置WebDriverAgent工程
3.1 克隆项目与依赖安装
WebDriverAgent是Facebook(现Meta)开源在GitHub上的项目,现在由Appium社区维护。我们直接从官方仓库获取最新代码。
打开终端,进入你准备存放项目的目录(例如~/Documents),执行克隆命令:
cd ~/Documents git clone https://github.com/appium/WebDriverAgent.git克隆完成后,进入项目目录:
cd WebDriverAgent接下来,使用carthage安装依赖。这个过程会下载并编译必要的第三方库,耗时取决于网络。
./Scripts/bootstrap.sh这个bootstrap.sh脚本内部其实就是调用了carthage bootstrap,但封装了一些针对WDA的特定参数。如果执行缓慢或失败,你可以尝试为carthage配置国内镜像,或者直接使用carthage bootstrap --platform iOS命令,并添加--cache-builds参数来利用缓存。
实操心得:
./Scripts/bootstrap.sh执行时,可能会在编译RoutingHTTPServer时卡住或报错。一个有效的解决方法是,可以手动编辑Cartfile文件,将其源从GitHub改为Gitee上的镜像(如果存在)。或者,更直接的办法是,多次重试。有时仅仅是网络波动。
3.2 使用Xcode打开并初览项目结构
在Finder中找到WebDriverAgent文件夹,双击打开WebDriverAgent.xcodeproj文件。这将启动Xcode并加载整个项目。
在Xcode左侧的项目导航器(Project Navigator)中,你会看到几个关键部分:
- WebDriverAgentLib:核心库,实现了WebDriver协议。
- WebDriverAgentRunner:这是一个测试靶包(Test Target)。这是我们配置和安装的重点。它不生成一个独立的App,而是一个可以被
xcodebuild命令启动的、包含UI测试代码的bundle。WDA服务实际上是在这个Runner的上下文中运行的。 - IntegrationApp:一个简单的示例应用,早期用于承载WDA,现在主要作为参考和备用方案。
我们的核心操作对象就是WebDriverAgentRunner这个Target。
4. 手动配置签名:攻克真机安装的核心难关
自动签名(Automatically manage signing)在简单应用中很方便,但WDA项目结构特殊,Xcode经常无法正确识别该为哪个Target配置描述文件,导致失败。因此,我强烈推荐并详细讲解手动配置流程。
4.1 创建App ID与描述文件
这一步需要在苹果开发者网站(developer.apple.com)进行。即使使用免费Apple ID,你也可以通过Xcode访问部分功能,但为了清晰,我们分步说明。
创建App ID:
- 登录开发者网站,进入“Certificates, Identifiers & Profiles”。
- 选择“Identifiers” -> “App IDs”,点击“+”创建。
- 选择“App”(默认),点击Continue。
- 描述(Description):填写一个易记的名字,如“WDA Runner”。
- Bundle ID:这是最关键的一步。必须采用显式(Explicit)格式,并严格匹配WDA项目中的Bundle Identifier。打开Xcode,选中
WebDriverAgentRunnerTarget,进入“Signing & Capabilities”选项卡,你可以看到默认的Bundle Identifier是com.facebook.WebDriverAgentRunner。我建议你修改成自己独有的,例如com.yourname.WebDriverAgentRunner,以避免和他人冲突。这里我们假设你使用com.yourname.WebDriverAgentRunner。 - 在网站上,将Bundle ID选择为“Explicit”,并填入
com.yourname.WebDriverAgentRunner。 - 一路Continue并Register完成创建。注意:不需要额外启用任何Capabilities(如Push Notifications)。
获取设备UDID:
- 将iPhone连接到Mac。
- 打开终端,使用之前安装的
libimobiledevice工具获取UDID:idevice_id -l - 你会看到一长串字母数字组合,这就是你设备的UDID。复制它。
- 备用方案:也可以通过Xcode(Window -> Devices and Simulators)或者iTunes查看UDID。
创建开发证书(如需):
- 如果你第一次使用,可能需要创建开发证书。在“Certificates”页面,点击“+”添加,选择“iOS App Development”,然后按提示操作(通常需要在Mac上生成一个证书签名请求文件
.certSigningRequest)。创建完成后,下载.cer文件并双击安装到钥匙串。
- 如果你第一次使用,可能需要创建开发证书。在“Certificates”页面,点击“+”添加,选择“iOS App Development”,然后按提示操作(通常需要在Mac上生成一个证书签名请求文件
创建开发描述文件(Provisioning Profile):
- 进入“Profiles”页面,点击“+”添加。
- 选择“iOS App Development”,点击Continue。
- 在App ID选择页面,选中你刚才创建的
com.yourname.WebDriverAgentRunner,点击Continue。 - 选择你刚才安装的开发证书,点击Continue。
- 选择你添加了UDID的设备(全选或单选你的测试机),点击Continue。
- 给描述文件命名,如“WDA Runner Development”,点击Generate。
- 生成后,下载这个
.mobileprovision文件到本地。
4.2 在Xcode中配置项目
现在回到Xcode,我们需要将证书和描述文件配置到项目中。
安装描述文件:双击下载的
.mobileprovision文件,它会自动安装到Xcode和系统中。你可以在Xcode的“Preferences -> Accounts -> 选择你的账号 -> Manage Certificates…”中看到已安装的描述文件,或者在~/Library/MobileDevice/Provisioning Profiles目录下找到它。配置WebDriverAgentRunner Target:
- 在Xcode项目导航器中,选中顶级的
WebDriverAgent项目(蓝色图标),在中间面板选择WebDriverAgentRunnerTarget。 - 切换到“Signing & Capabilities”选项卡。
- 取消勾选“Automatically manage signing”。这是关键一步。
- 在“Team”下拉框中,选择你的个人团队(通常显示为你的名字 (Personal Team))。
- 在“Provisioning Profile”下拉框中,选择你刚刚创建并安装的“WDA Runner Development”(或者类似名称)。如果下拉框里没有,可以点击“Import Profile…”手动选择
.mobileprovision文件。 - 选择后,“Signing Certificate”应该会自动匹配到你的开发证书。
- 检查“Bundle Identifier”是否与你网站上创建的App ID完全一致(本例中是
com.yourname.WebDriverAgentRunner)。
- 在Xcode项目导航器中,选中顶级的
配置WebDriverAgentLib Target(可选但推荐):
- 同样在项目设置中,选择
WebDriverAgentLibTarget。 - 也取消“Automatically manage signing”,Team选择同一个,Provisioning Profile选择“None”或“Automatic”即可,因为这是一个库,不需要安装到设备。但设置相同的Team可以避免编译警告。
- 同样在项目设置中,选择
核心注意事项:很多配置失败都源于Bundle Identifier不匹配。Xcode中的Bundle Identifier、开发者网站上App ID的Bundle ID、描述文件中绑定的App ID,这三者必须一字不差。一个大小写错误或一个字符差异都会导致安装失败,报错“A valid provisioning profile for this executable was not found.”
5. 编译与安装到真机
配置完成后,我们就可以尝试将WDA安装到手机上了。我们将使用命令行工具xcodebuild,因为它更清晰、可脚本化。
5.1 使用xcodebuild命令编译安装
首先,确保手机已解锁并连接到Mac。在终端中,进入你的WebDriverAgent项目目录。
执行以下命令进行编译和安装:
xcodebuild -project WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination ‘id=<你的设备UDID>’ test请将<你的设备UDID>替换为你之前用idevice_id -l获取的真实UDID。
命令拆解:
-project WebDriverAgent.xcodeproj:指定要编译的工程文件。-scheme WebDriverAgentRunner:指定编译方案(Scheme),我们针对Runner。-destination ‘id=UDID’:指定部署目标,即你的具体设备。test:这是一个关键参数。它告诉Xcode执行“测试”动作,这会将Runner构建并安装到设备,然后启动测试(即启动WDA服务)。如果只用build,则只会编译不会安装运行。
执行这个命令后,Xcode会开始编译。第一次编译会较慢,因为它需要处理依赖和索引。编译成功后,会自动安装到你的手机。
此时,查看你的iPhone屏幕:你应该会看到手机上安装了一个新的“应用”,图标是白色的,名字叫WebDriverAgentRunner。但点击它无法打开,这是正常的,因为它是一个测试Runner,不是独立App。它的使命是在后台启动服务。
5.2 信任开发者证书
安装后,第一次运行前,必须在iPhone上进行授权。
- 打开iPhone的“设置”应用。
- 进入“通用” -> “VPN与设备管理”(或“设备管理”)。
- 你应该会看到一个“开发者应用”分区,下面显示着你的Apple ID邮箱。
- 点击它,然后点击“信任“[你的邮箱]””。
- 在弹出的对话框中,再次点击“信任”。
完成这一步,设备才允许运行你(这个开发者)签名的应用。
5.3 启动WDA服务
信任证书后,我们再次启动WDA服务。在终端中重新执行一次上面的xcodebuild test命令。或者,更常见的做法是,我们让服务在后台持续运行。
执行以下命令启动服务,并让它在设备后台运行:
xcodebuild -project WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination ‘id=<你的设备UDID>’ test-without-building注意参数变成了test-without-building。这个命令会假设应用已安装,直接启动它(运行测试),而不重新编译。这通常用于后续的启动。
如果一切顺利,你将在终端看到大量日志输出,最后会出现类似以下的成功信息,并保持运行状态(不会退出):
... Test Suite ‘All tests’ started at 2023-10-27 10:00:00.000 Test Suite ‘WebDriverAgentRunner.xctest’ started at 2023-10-27 10:00:00.001 Test Case ‘-[UITestingUITests testRunner]’ started. t = 0.00s Start Test at 2023-10-27 10:00:00.002 t = 0.00s Set Up这表明WDA服务已经在你的iPhone上启动成功了。它启动了一个HTTP服务器。
6. 连接验证与端口转发
6.1 验证服务状态
WDA服务默认在设备的8100端口启动。但由于iOS的安全沙盒,Mac无法直接通过iPhoneIP:8100访问。我们需要使用端口转发。
在新开一个终端标签页或窗口中,使用iproxy工具(由libimobiledevice提供)进行端口转发:
iproxy 8100 8100 <你的设备UDID>这个命令将设备上的8100端口映射到本机(Mac)的8100端口。现在,你可以在Mac的浏览器中访问http://localhost:8100/status。
你应该能看到一个JSON格式的响应,类似于:
{ “value”: { “message”: “WebDriverAgent is ready to accept commands”, “state”: “success”, “os”: {…}, “ios”: {…}, “build”: {…} }, “sessionId”: null }这证明WDA服务运行正常,并且已经准备好接收WebDriver协议命令(例如来自Appium的命令)。
6.2 访问设备Inspector
WDA还提供了一个强大的网页版Inspector工具,用于查看设备UI层级结构。在浏览器中访问http://localhost:8100/inspector。
首次访问可能会加载较慢。加载完成后,你会看到一个网页,中间是你的设备屏幕镜像(可能是黑屏或当前界面)。点击“Start”按钮,它就会开始实时显示手机屏幕,并且你可以点击页面上的元素,右侧会显示该元素的详细属性(如name, label, value, type, xpath等)。这个工具对于编写和调试自动化测试脚本的定位器(Locator)至关重要。
重要提示:
inspector页面依赖于WebSocket连接来传输实时屏幕图像。如果遇到无法连接、黑屏或卡顿,请检查:
iproxy命令是否在运行。- 手机和Mac是否在同一Wi-Fi网络?虽然我们通过USB连接,但Inspector的WebSocket连接有时会尝试走网络。确保手机Wi-Fi和Mac网络可互通,或者尝试在手机端关闭Wi-Fi(仅用USB),有时反而更稳定。
- 浏览器控制台(Console)是否有WebSocket连接错误。
7. 常见问题排查与实战技巧实录
配置WDA的过程很少一帆风顺。下面是我总结的常见“坑”及其解决方案。
7.1 签名与安装类问题
问题1:编译失败,报错“Signing for “WebDriverAgentRunner” requires a development team.”
- 原因:没有为Target选择Team,或者自动签名被禁用后未手动选择。
- 解决:严格按照第4.2节,为
WebDriverAgentRunnerTarget手动选择Team和描述文件。
问题2:安装到设备时失败,报错“A valid provisioning profile for this executable was not found.”
- 原因:这是最经典的错误。根本原因是三处Bundle Identifier不匹配或描述文件未包含当前设备。
- 排查步骤:
- 核对Bundle ID:检查Xcode中
WebDriverAgentRunner的Bundle Identifier、开发者网站App ID的Bundle ID、描述文件绑定的App ID,三者必须完全一致。注意大小写。 - 核对设备:在开发者网站,确认你设备的UDID已添加到描述文件所关联的设备列表中。
- 核对证书类型:确保描述文件绑定的是开发(Development)证书,而不是发布(Distribution)证书。
- 清理重试:在Xcode菜单栏选择 Product -> Clean Build Folder。然后删除手机上的
WebDriverAgentRunner应用。重新执行xcodebuild命令。
- 核对Bundle ID:检查Xcode中
问题3:在设备上点击“信任”后,运行应用立刻闪退。
- 原因A:证书或描述文件已过期。免费个人开发者证书有效期只有7天,描述文件有效期通常为1年。
- 解决A:重新在开发者网站生成新的开发证书和描述文件,下载并安装到Mac,然后在Xcode中更新Provisioning Profile的选择。
- 原因B:WDA服务内部崩溃。这可能是代码或依赖问题。
- 解决B:尝试完全重新克隆项目,并重新执行
./Scripts/bootstrap.sh。确保使用Xcode命令行工具:sudo xcode-select -s /Applications/Xcode.app/Contents/Developer。
7.2 连接与运行类问题
问题4:执行xcodebuild test命令后,长时间卡在“Running tests…”或没有任何反应。
- 原因:可能是之前的测试进程没有正常结束,僵尸进程占用了资源。
- 解决:
- 在手机上手动强制关闭
WebDriverAgentRunner应用(如果能看到)。 - 在Mac上,打开“活动监视器”,搜索“WebDriver”或“xcodebuild”,将相关的进程全部“强制退出”。
- 重启iPhone。这是一个非常有效的“万能”方法。
- 重新运行命令。
- 在手机上手动强制关闭
问题5:访问http://localhost:8100/status或/inspector超时或无法连接。
- 原因A:
iproxy端口转发未启动或已断开。 - 解决A:确保在另一个终端窗口运行着
iproxy 8100 8100 UDID命令,并且没有报错。 - 原因B:WDA服务并未成功启动。检查运行
xcodebuild的终端,是否有错误日志,是否显示测试已启动。 - 解决B:重新运行
xcodebuild -project … test-without-building命令启动服务。 - 原因C:防火墙或网络代理干扰。
- 解决C:暂时关闭Mac的防火墙,或检查网络代理设置是否拦截了本地回环地址
127.0.0.1的流量。
问题6:Inspector页面黑屏,或者元素无法交互。
- 原因:WebSocket连接不稳定或权限问题。
- 解决:
- 确保手机和Mac在同一个局域网,或者尝试关闭手机的Wi-Fi(仅用USB)。
- 在iPhone的“设置 -> 屏幕使用时间 -> 内容和隐私访问限制 -> 屏幕录制”,确保
WebDriverAgentRunner应用被允许(如果有此选项)。不同iOS版本位置可能不同。 - 尝试使用
wda的startRecordingScreen和stopRecordingScreen命令来间接判断屏幕访问能力。
7.3 进阶配置与优化技巧
技巧1:修改WDA启动参数WDA的启动行为可以通过在Xcode中为WebDriverAgentRunnerTarget添加“Environment Variables”来调整。在Scheme设置中(Product -> Scheme -> Edit Scheme -> Run -> Arguments),添加环境变量:
USE_PORT: 指定服务端口,如8100。MJPEG_SERVER_PORT: 指定屏幕流端口,如9100。STARTUP_TIMEOUT: 设置启动超时时间(毫秒)。 修改后需要重新编译安装。
技巧2:实现无需USB的Wi-Fi连接(无线调试)一旦通过USB成功启动一次WDA,并且设备与Mac在同一Wi-Fi下,可以尝试断开USB,让WDA通过Wi-Fi连接。
- 确保手机和Mac在同一网络,且能互相ping通。
- 在手机上查看WDA服务的真实IP和端口。可以在WDA启动日志中查找,或者安装一个网络工具App查看。
- 在Mac上,直接通过
http://<手机IP>:8100/status访问。如果成功,则Appium等工具也可以配置使用这个IP地址,实现无线自动化测试。这非常利于多设备测试和持续集成。
技巧3:处理系统弹窗(如权限提示)自动化测试中,处理“是否允许通知”、“是否允许访问照片”等系统弹窗是个难点。WDA本身不直接处理这些。通常需要借助其他方式:
- 在Appium中,可以使用
mobile: alert接口。 - 更根本的方法是,在首次手动安装测试时,就处理完所有权限弹窗,或者使用苹果的
.mobileconfig配置文件预置权限(需企业证书)。
8. 与Appium集成:让WDA发挥价值
单独运行的WDA只是一个提供了WebDriver协议接口的服务。它的真正威力在于与Appium这样的高级测试框架结合。
启动Appium Server:确保你已安装Appium(如通过
npm install -g appium)。在终端运行appium启动服务。编写测试脚本(以Python为例):
from appium import webdriver from appium.options.ios import XCUITestOptions # 配置Capabilities options = XCUITestOptions() options.platform_name = ‘iOS’ options.automation_name = ‘XCUITest’ # 必须为XCUITest options.device_name = ‘iPhone 13’ # 任意名称,用于日志 options.platform_version = ‘16.0’ # 你的手机系统版本 options.bundle_id = ‘com.apple.Preferences’ # 要测试的App的Bundle ID,这里以系统设置为例 options.udid = ‘<你的设备UDID>’ # 至关重要! # 关键:告诉Appium使用已启动的WDA options.web_driver_agent_url = ‘http://localhost:8100’ # 如果WDA运行在本机转发端口 # 连接Appium Server和WDA driver = webdriver.Remote(‘http://localhost:4723’, options=options) # 执行你的测试操作,例如打开设置 # … (你的测试代码) driver.quit()注意
web_driver_agent_url这个配置项。它告诉Appium不要自己再去启动一个新的WDA实例,而是连接我们刚才手动启动好的那个。这种方式更稳定,也便于调试。运行脚本:确保WDA服务(通过
xcodebuild)和iproxy都在运行,然后执行你的Python脚本。Appium Server会将接收到的命令转发给本机的WDA服务,进而控制你的iPhone。
通过以上步骤,你就搭建起了一个完全由自己掌控的、稳定的iOS自动化测试底层环境。从此,Appium的运行不再是一个黑盒,你知道它的每一步背后发生了什么,当出现问题时,你也能够深入到WDA这一层进行排查。这份从零到一搭建的经验,是理解iOS自动化测试体系不可或缺的基石。