资讯动态

M1 Mac UI自动化环境搭建实战:Web端与移动端全攻略

发布时间:2026/10/20 8:58:06 来源:尧图企业网站定制
1. 动手前的关键判断M1 上跑 UI 自动化到底难在哪先说我的结论M1 芯片的 Mac 上搭建 UI 自动化环境不是装不上软件而是很多旧教程默认你是 x86 平台照抄下来会踩到架构相关的坑。如果你是从 Intel Mac 换过来的测试开发第一周大概率会遇到这种场面Python 装好了Selenium 也 pip 成功了一启动 Chrome 驱动就报 “exec format error”或者 Appium 装了半天模拟器里 WebDriverAgent 编译失败日志里全是 “does not contain a valid arm64 slice”。这些问题的根源都指向同一个词arm64。M1 是 ARM 架构和 Intel 时代的 x86_64 指令集不通用。UI 自动化链条里最底层的那些组件——浏览器驱动、移动端测试框架、各种运行时——如果拿到的还是 Intel 版本系统要么通过 Rosetta 转译运行要么直接拒绝加载。转译能临时解决问题但在正式项目里会带来两个隐患一是性能损耗二是环境差异容易在团队里引起“我这能跑怎么你那不行”的低级事故。所以我这次搭建的原则很明确凡是能用 arm64 原生版本的一律不用转译凡是必须转译的单独隔离环境并写清楚备注。这篇文章的目标读者我猜大概有三类刚入手 M1/M2 Mac 的测试工程师正在给团队搭自动化测试框架的人以及被“教程都是 Windows/Intel 版本”折磨到想砸电脑的初学者。你不需要多深的后端功底但至少要会打开终端、能照抄命令、知道 pip/npm 大概是干嘛的。我会把从零搭建到跑通第一个用例的完整过程拆开讲每个选择后面都解释为什么希望你看完之后不只是“装好了”还能在以后遇到新架构问题时知道排查方向。严格来说M1 带来的问题并不是“不能做自动化”而是“做自动化的方式变了”。Web 端无非是浏览器驱动要选对架构移动端则是模拟器、签名、编译这些环节有了新的隐含要求。我把整个过程拆成四层基础工具链、Web 自动化、移动自动化、问题排查。下面一步步来。2. 基础工具链先让终端跑在正确的架构上2.1 确认当前终端到底是哪种架构很多人搭建环境的第一步就错了直接在自带终端里装软件根本不知道自己装的包是 arm64 还是 x86_64。M1 Mac 上默认的 Terminal 跑的是 arm64但它可以调用 Rosetta 转译的 zsh 来模拟 x86_64 环境。装了 Homebrew 之后有的软件会自动落到正确路径有的则不会。先执行这条命令确认当前终端架构arch如果输出arm64说明你的终端原生运行在 Apple Silicon 下。如果输出i386或x86_64说明当前终端套了一层 Rosetta后续装的 Homebrew、Python、Node 都会变成 x86_64 版本这就是很多莫名其妙的兼容性问题的来源。另一个判断技巧是看 Homebrew 的安装路径。Apple Silicon 下 Homebrew 统一在/opt/homebrewIntel Mac 则在/usr/local。如果你发现自己的 brew 在/usr/local下基本可以断定这是通过 Rosetta 装的。从现网经验看很多开发者一开始图省事直接用备份迁移工具从旧 Mac 恢复了环境导致/usr/local里的旧版 brew 被带到新机器上后面所有包都乱了套。2.2 Homebrew 安装与路径规划我推荐的做法是先把旧的 x86_64 Homebrew 清理干净再重新安装原生版。官方安装命令是/bin/zsh -c $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)装完之后把环境变量写进 shell 配置。新建的 M1 Mac 一般不会自动加入 PATH你需要手动加echo export PATH/opt/homebrew/bin:$PATH ~/.zshrc source ~/.zshrc这里有个我踩过的坑安装脚本会提示你 “Next steps” 并把两行export命令展示出来很多人忽略了这一步结果 brew 命令找不到。更隐蔽的问题是如果以后用sudo调 brewPATH 可能会丢失最好在/etc/paths里也把/opt/homebrew/bin加上。还有一点M1 Mac 上不要轻易用 sudo 去改/usr/local的权限。Intel 时代很多人习惯sudo chown -R $(whoami) /usr/local这在 M1 上是不需要的而且可能会把权限模型搞乱后续卸载软件时非常痛苦。2.3 Python 环境纯净安装还是管理工具Python 是整个自动化链路里最容易产生分歧的环节。M1 Mac 自带 Python 3来自 Command Line Tools但版本一般比较旧而且pip3装全局包会影响系统环境不建议直接拿来用。我更推荐用 Miniconda 管理 Python因为它在 Apple Silicon 下提供了官方osx-arm64版本能很干净地隔离环境。下载地址是官方渠道的 Miniconda3 macOS Apple Silicon 安装包安装完以后用conda create -n autotest python3.11建一个专用环境。如果你不喜欢 conda也可以用 Homebrew 的方式brew install python3.11这样得到的也是 arm64 原生 Python。但要注意不要同时用 conda 和 brew 装的两套 Python 互相覆盖 PATH否则会出现“pip 装包装到另一个 Python 里”的诡异问题。我自己的建议是整个团队统一用 conda少折腾 PATH。在自动化环境里conda 还能顺手管理 JDK 之外的某些二进制依赖虽然不常用但多一层保障不是坏事。2.4 Node.js 与 Java按需选择别一股脑全装Web 自动化只需要 Python但如果你要跑 Appium必须装 Node.js。M1 Mac 上装 Node 有两个主流路线通过 Homebrewbrew install node默认最新 LTSarm64 原生。通过 nvmcurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash然后nvm install --lts。装完之后验证一下是否原生node -p process.arch输出arm64就没问题如果输出x64说明 Node 是 Rosetta 转译版建议卸载重装。Node 的架构不一致会影响 Appium 里某些二进制依赖的加载尤其是后面要装appium-driver-xcuitest时非常明显。Java 主要用于 Android 测试。如果你只做 iOS 端的 Appium 测试JDK 可以先不装如果要做 Android建议装 OpenJDK 17 或 21。用 Homebrew cask 装brew install --cask temurin17装完检查/usr/libexec/java_home -V这一步的目的和前面一样确认 JDK 是 aarch64 架构。如果列出了 x86_64 的路径说明装了 Intel 版需要去手动删除再重装。我见过不止一次团队成员因为 JDK 架构不对导致adb服务启动失败报错信息还特别隐晦。到这里基础层已经齐了。整理一下当前的状态Homebrew 原生运行、Python 3.11conda 环境或 brew 环境、必要时 Node LTS、可选 JDK。这个基础层一旦搭好后面的所有环节都顺很多。3. Web 端 UI 自动化Selenium 与浏览器驱动的完整落地3.1 浏览器驱动选型M1 真正要小心的地方Web UI 自动化的核心是 Selenium它本身是纯 Python 库架构问题不大真正的坑在浏览器驱动。以 Chrome 为例。Chrome 浏览器在 M1 上默认安装的是 arm64 版本这在系统层面是没问题的但 chromedriver 必须和浏览器版本精确匹配。过去很长一段时间chromedriver 官方下载页里只提供 mac64 和 mac64_m1 两个大类下载错了就会出现 “cannot find Chrome binary” 或启动直接崩溃。从 Chrome 115 开始官方推出的 Chrome for Testing 机制基本解决了这个问题。你只需要进入 Chrome for Testing 的下载页面选chromedriver-mac-arm64版本就行。如果你图省事用了普通 mac64 版本在 M1 上也不是百分百跑不起来因为 Rosetta 有时能兜底但报错时的排查成本远高于省下的那点下载时间。基本原则先确认 Chrome 浏览器版本再下载完全一致或最接近的 chromedriver 版本。查看 Chrome 版本的路径是浏览器地址栏输入chrome://version。在自动化脚本里也可以用 Selenium 自带的 Selenium Manager 自动下载驱动这个功能从 Selenium 4.11 开始已经很稳定了但我仍然建议在正式项目里手动锁定 chromedriver 版本原因有两个一是自动下载的驱动版本有时候会超前于生产环境的 Chrome 导致兼容问题二是自动化测试最怕“环境不确定”手动锁版本意味着任何一员复现环境时结果一致。3.2 安装 chromedriver 并配置 PATH下载完chromedriver-mac-arm64.zip之后把它解压到一个固定的目录比如~/tools/chromedriver/。然后把它加入 PATHexport PATH$HOME/tools/chromedriver:$PATH为了让配置持久化请把它写进~/.zshrc。这里有个非常容易犯的错误直接把 chromedriver 扔到/usr/local/bin就以为完事了。在 M1 上/usr/local/bin一般不存在或者权限很怪我不推荐这么做。接下来在终端里验证驱动是否可用chromedriver --version出现版本号之后跑一个最简单的 Selenium 脚本验证整条链路from selenium import webdriver options webdriver.ChromeOptions() driver webdriver.Chrome() # 如果 chromedriver 在 PATH 里这里会自动探测 driver.get(https://example.com) print(driver.title) driver.quit()如果这一步出现了 “WebDriverException: unknown error: cannot find Chrome binary”别急着怀疑 Selenium先检查 Chrome 是不是真的装到了 M1 Mac 的应用程序目录。还有一种情况你装的是 Chrome Beta 或 Chromium那需要用binary_location显式指定路径options.binary_location /Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary3.3 SafariDriver苹果原生方案其实更省心如果你的测试场景不需要跨浏览器Safari 的自动化驱动是个几乎零成本的选择。macOS 自带 safaridriver路径在/usr/bin/safaridriver。只需要先在系统设置里开启“允许远程自动化”然后代码里把 browser 指定为 safarifrom selenium import webdriver driver webdriver.Safari() driver.get(https://example.com) print(driver.title) driver.quit()注意Safari Driver 首次启动时可能提示“无法创建会话”因为需要在系统设置中打开“开发者模式”或执行一次授权命令safaridriver --enable这条命令会要求输入管理员密码。我推荐把 Safari 作为一个备选方案写在自动化框架里尤其是当 Chrome 驱动升级导致用例批量失败时Safari 能临时顶上。3.4 处理浏览器自动更新的架构匹配问题Web 端自动化最大的日常敌人其实是浏览器自动更新。Chrome 每次自动升级后chromedriver 版本就旧了大概率出现 SessionNotCreatedException。常用的对策有这些锁定 Chrome 版本macOS 上可以用brew install --cask google-chromexxx装指定版本但维护成本偏高。封装驱动下载脚本写一个 shell 脚本在跑测试前检查 Chrome 版本并从 CDN 拉取对应的 chromedriver。不建议把这事做太复杂一个 20 行以内的脚本足够。使用 Selenium Manager 兜底在本地开发环境让它自动匹配在 CI 里用固定版本。我在实际项目里是这么做的开发阶段完全依赖 Selenium Manager 自动匹配省心但进入回归测试阶段之前会跑一遍自检脚本锁定版本避免“上午还能跑下午全挂”的经典场面。3.5 动手跑一个带登录流程的用例理论部分差不多了我们来跑一个真实感强一点的示例自动打开一个简单的待测站点、登录、校验页面元素。把下面代码保存为demo_login.py运行前确保 Chrome 和 chromedriver 路径正常。import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC options webdriver.ChromeOptions() options.add_argument(--window-size1440,900) # 如果你在公司内网做测试可能需要这段来绕过证书问题 # options.add_argument(--ignore-certificate-errors) driver webdriver.Chrome(optionsoptions) try: driver.get(http://your-test-site.com/login) # 显式等待比 time.sleep 更稳 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.NAME, username)) ).send_keys(demo_user) driver.find_element(By.NAME, password).send_keys(demo_pass) driver.find_element(By.CSS_SELECTOR, button[typesubmit]).click() WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, user-panel)) ) print(登录成功页面标题, driver.title) finally: driver.quit()在 M1 Mac 上跑这个脚本最直观的体验是速度。原生 arm64 的 Chrome 比 Rosetta 转译版在渲染复杂页面时快不少等待元素出现的超时率也明显降低。我曾在一台老 Intel 笔记本上跑同一个脚本平均要 8 秒完成M1 Mac 上只要 3~4 秒这对回归测试的耗时优化很有帮助。另外一个 M1 特有的加分项是“硬件加速渲染”。Apple Silicon 的 GPU 单元和 Chrome 的渲染管线配合得很好如果测试涉及大量截图你可以明显感觉到截图速度更快、卷更长。4. 移动端 UI 自动化Appium 在 M1 Mac 上的完整配置4.1 准备工作Xcode 与模拟器移动端自动化在 Mac 上的主力工具是 Appium。iOS 方向绕不开 Xcode因为 WebDriverAgent 需要在 Xcode 里编译并安装到模拟器。M1 Mac 上安装 Xcode 很简单直接 App Store 搜索下载即可但有几个前置依赖安装 Xcode Command Line Toolsxcode-select --install。首次打开 Xcode同意许可协议等待组件初始化。打开 Xcode 的 Settings在 Components 里下载你需要的 iOS 模拟器版本比如 iOS 17 或 iOS 18。这里有一个高频坑如果你的测试机团队里有人用 iOS 16有人用 iOS 17模拟器版本混着用没问题但你必须在 Xcode 里预先下载对应版本的 simulator runtime否则 Appium 启动时会报 “No simctl devices found in the list” 之类的问题。命令行工具simctl是我们后面判断模拟器状态的关键。用xcrun simctl list devices可以看当前可用的所有模拟器。建议把测试目标锁定在最少一个模拟器上而不是 “所有可用模拟器”这样 Appium 启动时不会因为多设备嵌套而变慢。4.2 安装 Appium 服务端和驱动Appium 本身是 npm 包安装命令npm install -g appium安装完成后用appium --version验证。这里要注意 npm 全局包的安装路径Apple Silicon 原生 Node 会把全局包安装到/opt/homebrew/lib/node_modules如果你用 nvm路径则是用户目录下具体看npm root -g的输出。接下来安装移动端驱动。Appium 4.0 之后采用 Driver 插件化机制iOS 的驱动叫xcuitestAndroid 的叫uiautomator2。安装命令分别是appium driver install xcuitest appium driver install uiautomator2这里我建议用appium driver list确认驱动状态。如果安装过程中卡在下载某些二进制文件多半是网络问题可以设置 npm 镜像源或者直接手动下载资源包放进 Appium 的缓存目录。记住不要在生产环境用全局卸载重装的方式折腾驱动容易导致依赖版本的隐性变化。4.3 WebDriverAgent 的编译与签名M1 上最大的坑Appium 跑 iOS 模拟器测试的核心机制是在模拟器里编译并启动一个叫 WebDriverAgentWDA的中间服务。它用 Xcode 构建作为一个 bridge 把 Appium 的命令转换成 iOS 系统的自动化操作。在 Intel Mac 时代这个步骤几乎是一路下一步但到了 M1 上你必须要理解两个问题第一个问题是架构切片。Xcode 默认会构建arm64和x86_64两个 slice但在某些 Xcode 版本下模拟器 SDK 里 arm64 的编译选项没有自动打开导致 WDA 启动时报 “unable to launch ... because it has an invalid architecture”。解决办法是在Appium的 xcuitest driver 配置里显式指定{ appium:platformVersion: 17.2, appium:deviceName: iPhone 15 Pro, appium:automationName: XCUITest, appium:udid: 模拟器 UDID, appium:xcodeOrgId: TEAMID, appium:xcodeSigningId: iPhone Developer }TEAMID来自你的 Apple ID 开发者团队如果没有付费开发者账号模拟器测试其实不一定需要签名但某些 WDA 版本会强制检查。如果你遇到签名报错可以去 Apple Developer 官网免费注册个人团队Personal Team虽然不能装到真机跑模拟器足够。第二个问题是编译器路径。WDA 构建时偶尔会用系统默认的clang而不是 Xcode 自带的工具链导致头文件找不到。解决办法是在 shell 配置里明确export DEVELOPER_DIR/Applications/Xcode.app/Contents/Developer这个配置我强烈建议写进~/.zshrc因为不少 M1 上 Xcode 相关的命令行工具都会读取它。4.4 配置 Appium 跑通第一个 iOS 模拟器用例配置好 WDA 之后启动 Appium 服务端appium --log-level debug然后在另一个终端里运行测试脚本。这里我用 WebDriverIO 的 Node 示例因为它在移动端生态里比 Python 更常见。但如果你熟悉 Python直接用 Appium Python Client 也一样。from appium import webdriver from appium.options.ios import XCUITestOptions options XCUITestOptions() options.platform_name(iOS) options.platform_version(17.2) options.device_name(iPhone 15 Pro) options.app(/path/to/your-app.app) # 模拟器安装的 app 包 driver webdriver.Remote(http://127.0.0.1:4723, optionsoptions)第一次启动时Appium 会尝试构建并安装 WDA耗时可能达到几分钟。如果一切顺利你会看到日志里出现 “WebDriverAgent start successfully” 之类的关键字。然后就能调用 Appium 的 API 去做点击、滑动、截图等操作了。M1 模拟器启动比 Intel 快很多arm64 原生编译的模拟器镜像在 Apple Silicon 上几乎秒开。这一点我实测下来体感非常明显Intel Mac 上启动一个 iOS 模拟器有时要等两分钟M1 上通常 15 秒以内。代价是 Android 模拟器在 M1 上的体验反而一般稍后讲。4.5 Android 补充ARM 镜像和模拟器加速Android 方向不是 M1 的强项。如果你是纯 Android 自动化且预算允许我更推荐用真实的 Android ARM 设备。如果你必须用模拟器注意几个点下载模拟器镜像时不要选 x86_64 镜像要选 ARM64 镜像。Google 官方在 Apple Silicon 上对 ARM64 镜像的支持已经逐步完善但启动速度和生态仍然不如 Intel Mac 时代的 HAXM 加速方案。M1 模拟器底层用的是 Apple Hypervisor.Framework这套机制本身没问题只是很多 Android 系统镜像还没有为它做深度优化。安装 Android SDK 的命令大概如下brew install --cask android-commandlinetools sdkmanager platform-tools platforms;android-33 emulator system-images;android-33;google_apis;arm64-v8a然后创建模拟器avdmanager create avd -n test_avd -k system-images;android-33;google_apis;arm64-v8a emulator -avd test_avd如果你发现模拟器启动后黑屏或系统卡顿先检查 CPU 虚拟化是否开启。在 M1 上Android 模拟器有时需要修改 AVD 的配置文件~/.android/avd/*.avd/config.ini将hw.cpu.arch显式设为arm64。这个细节不写在官方文档的显眼位置但遇到问题的人很多。5. 高频问题速查我在 M1 上真实踩过的坑搭建环境的过程中我前前后后解决了不少问题。挑几个最高频的列成清单每个都是我在实际操作中遇到的解决方案也都验证过。问题一chromedriver启动后直接崩溃报错Invalid argument现象Selenium 脚本执行到webdriver.Chrome()时崩溃终端打印[26716:26716:XXXX ERROR:command_buffer_proxy.cc(127)] ...原因chromedriver 和 Chrome 版本不匹配或者 chromedriver 是 Intel 版而被 Rosetta 转译。解决用chrome://version查浏览器版本下载对应的mac-arm64驱动并替换。不要只替换文件要删除旧的缓存文件再重启终端。问题二Appium 启动时提示Could not find a valid iOS device现象appium能启动但xcuitest找不到模拟器。原因模拟器没启动或者platformVersion填错了。解决先用xcrun simctl list devices available查看可用设备 UDID再把 UDID 填进 Desired Capabilities 里。建议显式指定udid比依赖设备名更稳定。问题三WDA 编译失败显示Code Signing Error现象Appium 日志里出现CodeSign error: code signing is required for product type UI Testing Bundle之类的文字。原因没有配置开发者团队或签名 ID 与 macOS 钥匙串中的证书不一致。解决去 Xcode 的 Accounts 里登录 Apple ID 并创建 Personal Team然后在appium: xcodeOrgId和appium: xcodeSigningId中正确填写。如果需要重新生成签名可以先运行xcodebuild clean清理缓存。问题四brew install某个包时卡在Updating Homebrew...很久现象终端长时间没有输出。原因网络问题Homebrew 默认从 GitHub 拉取版本更新。解决在~/.zshrc里设置export HOMEBREW_NO_AUTO_UPDATE1跳过自动更新。如果依赖下载慢可以考虑换镜像源但不要同时配置多个源否则会索引错乱。问题五Python 的pip install安装某些包时报Building wheel失败现象比如安装lxml或pandas这类带原生代码的包时编译失败。原因有些包的轮子还没提供 arm64 版pip 会尝试从源码编译然后缺少依赖。解决优先使用conda install安装这类包因为 conda 的 osx-arm64 渠道有更多预编译包。如果必须用 pip可以先brew install pkg-config或补齐对应的编译依赖。实在不行可以临时用 Rosetta 终端创建一个 x86_64 的 Python 环境只在这个环境里装那些还没朋友适配的包arch -x86_64 /bin/zsh conda create -n x86_env python3.11问题六模拟器截图出现花屏或黑屏现象Appium 调用 screenshot 接口返回的图片无法正常显示。原因模拟器图形渲染层面和自动化的截图接口偶发不兼容多发生在 Android 模拟器上。解决重新启动模拟器或在 AVD 配置文件里调低hw.gpu.mode为swiftshader_indirect。对 iOS 模拟器来说这个问题很少见如果出现先检查 WDA 版本是否过旧。问题七Node 全局安装的 appium 命令找不到现象npm 明明显示安装成功但appium命令提示 not found。原因npm 全局 bin 路径未加入 PATH。解决运行npm config get prefix把输出目录下的bin加进 PATH。如果是 nvm 环境切换 Node 版本后全局包可能过期需要重新安装。问题八M1 上 Firefox 自动化时 geckodriver 无法启动现象webdriver.Firefox()运行后报Expected browser binary location, but unable to find binary in default location原因Firefox 装到了自定路径或者 geckodriver 版本不对。解决M1 上 Firefox 是 arm64 原生应用正常安装路径在/Applications/Firefox.app。geckodriver 下载时务必选macos-aarch64版本然后在代码里指定driver webdriver.Firefox(executable_path/path/to/geckodriver)能用 Phyper 完全不用动底层二进制算是最省心的浏览器之一。如果你有跨浏览器测试需求建议把它放到第二优先级。6. 团队协作视角环境一致性比个人折腾更重要搭建单人开发环境是第一步但做测试的人都知道真正痛苦的是“在我电脑上能跑”这句话。M1 平台因为架构分裂环境一致性问题被放大了一个等级。我在实际项目里见过三种典型的翻车现场团队里有人用 Window x64有人用 M1代码里写死了/usr/local/bin/chromedriver路径M1 同事一执行就报错。有人用 Intel Mac 下载了 x64 版本浏览器驱动提交到共享资源目录M1 同事拿下来直接用全组测试失败。有人通过 Rosetta 装了 Node 和 Appium代码逻辑没问题但启动时间比原生版慢了两三倍被人误判成性能回归。这些问题不能只靠“大家注意一下”来解决。比较好的做法是把环境初始化过程写成一个脚本纳入项目仓库的scripts/env_setup.sh让每个人拉下代码后直接执行而不是翻文档一条条手动敲。脚本里至少要做这些事情# 1. 检测架构 ARCH$(uname -m) echo 当前架构: $ARCH if [ $ARCH ! arm64 ]; then echo 请注意当前非 Apple Silicon 原生架构本脚本按 Intel 兼容模式运行。 fi # 2. 安装 Homebrew如果没有 if ! command -v brew /dev/null; then /bin/zsh -c $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh) fi # 3. 安装 Python 环境 brew install python3.11 || true # 4. 安装 chromedriver 和 geckodriver # 这里需要根据 arch 选择下载地址把架构检查放在脚本最前面是有意义的当整个团队都跑同一套脚本时早一分钟发现架构不一致就少一小时排查问题的时间。此外如果你有 CI/CD 环境建议在流水器里区分两个标签arm64-runner和x64-runner。不要侥幸想着一个 runner 跑所有架构。M1 上的自动化用例完全可以放到 macOS arm64 的 runner 上但某些只提供了 x64 二进制的第三方工具会反过来拖累整体构建这时候宁可让它们跑在 Intel runner 上也不要强行统一环境。再从工具选择的角度说一句如果你的团队规模不大强烈建议把自动化用例的“环境依赖”收敛到最少。少一个系统级依赖就意味着架构问题少一个分支。比如behave和pytest都能写 Selenium 用例但pytest的生态里插件更多、对 arm64 适配也更积极那就优先选pytestAppium 客户端语言里Python 和 Node 都行但如果你要用 WebDriverAgent 调试日志Node 生态更顺那就统一用 Node。环境细节这种东西看起来小一旦爆发就是全组事故。我现在的习惯是每次升级浏览器驱动、换 Xcode 版本或者升级 Appium 驱动后都会在 CHANGELOG 里记一笔对应的架构和版本号。有人问我“这环境怎么搭的”直接翻仓库的历史记录比自己梳理一遍大脑清楚得多。7. 收尾一些散装但重要的实操经验最后这节我不想再写流程化的东西专门分享几个散装心得顺便把这些内容当作对前面所有知识的一个串联。第一M1 Mac 上做 UI 自动化前端速度体验是最容易被低估的优点。上面说了不少坑但如果你现在正处于“要不要换 M1/M2 Mac 来做测试开发”的决策点我可以负责任地说Apple Silicon 带来的性能提升在 UI 自动化场景下的感知非常直接。最明显的是模拟器启动和浏览器渲染其次是编译 WDA 的时间。同样一个项目Intel Mac 上整个准备流程需要 30 分钟M1 上 10 分钟就能进入用例执行阶段。这个效率差异直接改变了日常迭代节奏——以前是“慢跑一次用例要安排时间”现在是“随时改随时跑”。第二不要过分依赖 Rosetta 兼容层。短期看Rosetta 确实可以让一些旧工具跑起来但它本质上是在模拟一套 x86 环境这有两个很难忍的问题一是装的依赖会污染环境你以为你在一个干净的 arm64 终端里实际上所有后面装的包都默认走 x86 版二是 Rosetta 转译的工具在 IO 密集型的操作上比如并发启动浏览器、持续截图隐隐有性能损失这些损失在用例一多的时候就会被放大。如果你是为了跑某个“只在 x64 上可用”的老旧公司内部工具那可以单独建一个 Rosetta 终端用完就走但测试开发环境的主终端我建议保持原生 arm64。第三日志和版本信息是最有用的排障工具。很多人遇到自动化环境问题第一反应是去查某篇资料但我更建议先自己跑一遍诊断命令。比如uname -m、node -p process.arch、python -c import platform; print(platform.machine())、appium driver list这些命令能帮你快速把环境状态钉死在一个明确的点上。把这三五个命令组合成一个doctor.sh脚本遇到问题先跑一遍比盲猜高效十倍。第四在 M1 上配置移动自动化时Xcode 的版本尽量不要追新太多。我遇到过太多次 Appium 和最新版 Xcode 不兼容导致的 WDA 编译失败。并不是说不能用新版而是如果你今天搭环境正好碰上 Appium 发布新版本请务必去官方发布页看一眼兼容性矩阵。我的习惯是选一个稳定了至少一个季度的 Xcode 版本配一个同期稳定版 Appium不要盲目升大版本。最后再分享一个小技巧macOS 里可以同时保存多个终端 Profile比如一个叫arm64-native一个叫x86-rosetta。你给前者配置纯原生环境变量后者只放转译工具。这样就算临时要跑一个老脚本你也有干净的隔离环境不需要在系统层面来回切换。做法是在终端设置里给每个 Profile 的启动命令指定不同的 shell# arm64-native Profile 启动命令 /bin/zsh # x86-rosetta Profile 启动命令 arch -x86_64 /bin/zsh这个技巧成本极低但极其好用。因为我个人在实际踩坑中最大的教训就是“环境的边界感”。UI 自动化本身已经够复杂了架构这个变量再混进来你不主动隔离它就会让你付出额外的工作量。搭建 M1 上的 UI 自动化环境说穿了就是两件事把架构搞对把版本锁住。希望这篇文章能帮你更快落地少走一点我已经踩过的弯路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑