CircleCI macOS镜像中Appium Server启动失败连接被拒问题咨询
CircleCI Mac环境Appium iOS测试4723端口连接拒绝问题排查
问题场景
在CircleCI Mac OS镜像环境的iPhone模拟器上运行Appium自动化测试,测试代码基于Python+Behave框架编写,初始使用的config.yml配置如下:
version: 2.1 orbs: macos: circleci/macos@2.2.0 jobs: example-job: macos: xcode: 12.4 steps: - checkout - run: name: Install appium server command: | sudo npm update -g sudo npm install appium sudo npm install wd - run: name: Start appium server command: appium & background: true - run: name: Installing Dependencies command: pip3 install -r requirements.txt - run: name: Run Test command: behave --tags=sanity workflows: example-workflow: jobs: - example-job
流水线执行时抛出如下连接拒绝错误:
MaxRetryError: HTTPConnectionPool(host='localhost', port=4723): Max retries exceeded with url: /wd/hub/session (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x106602a60>: Failed to establish a new connection: [Errno 61] Connection refused'))
流水线执行截图:
根因分析
- 启动命令转义错误:配置中
appium &是HTML转义写法,Shell无法识别&为后台运行标识符,Appium进程根本没有正常在后台驻留,4723端口没有进程监听,直接导致连接拒绝。 - 缺少服务就绪校验:即使Appium正常启动,服务初始化、加载驱动、绑定端口需要数秒到数十秒(CI环境资源受限,耗时比本地更长),配置中启动Appium后直接执行测试步骤,测试发起连接时服务可能还未完成端口绑定。
- 缺少iOS测试必需依赖:Appium 2.x版本默认不内置任何平台驱动,仅安装主程序无法运行iOS测试,必须额外安装XCUITest驱动;使用sudo全局安装npm包还可能触发权限问题,导致Appium启动异常。
- 版本适配问题:Appium 2.x默认服务基础路径为
/,旧版测试代码常用的/wd/hub路径无法直接访问,即使服务启动也会出现请求失败。
解决方案
修改后的可用config.yml配置如下,已修复上述所有问题:
version: 2.1 orbs: macos: circleci/macos@2.2.0 jobs: example-job: macos: xcode: 12.4.0 steps: - checkout # 配置用户级npm路径,避免sudo安装带来的权限问题 - run: name: Configure npm environment command: | npm config set prefix ~/.npm-global echo 'export PATH=~/.npm-global/bin:$PATH' >> $BASH_ENV source $BASH_ENV - run: name: Install Appium and iOS driver command: | npm install -g appium npm install -g wd # 安装iOS测试必需的XCUITest驱动 appium driver install xcuitest - run: name: Start Appium and wait for service ready command: | # 后台启动Appium,指定日志路径、兼容旧版/wd/hub路径,按需调整参数 appium --base-path /wd/hub --log appium.log & # 轮询检测4723端口,最多等待30秒 for i in {1..30}; do if nc -z localhost 4723; then echo "Appium service started successfully" break fi echo "Waiting for Appium to bind port..." sleep 1 done # 等待超时直接输出日志并终止任务 if ! nc -z localhost 4723; then echo "Appium start failed, log as below:" cat appium.log exit 1 fi background: true - run: name: Install Python dependencies command: pip3 install -r requirements.txt # 提前启动目标iOS模拟器,避免测试阶段模拟器冷启动超时 - run: name: Boot target iOS simulator command: | # 替换为你测试用的设备、系统版本 TARGET_DEVICE_ID=$(xcrun xctrace list devices | grep "iPhone 12" | grep "14.4" | awk -F'[()]' '{print $2}' | head -1) xcrun simctl boot $TARGET_DEVICE_ID || true open -a Simulator - run: name: Run sanity test cases command: behave --tags=sanity # 无论测试成功失败都输出Appium日志,方便排查问题 - run: name: Output Appium runtime log command: cat appium.log when: always workflows: example-workflow: jobs: - example-job
额外注意事项
- 不要在CI环境中使用sudo安装npm全局包,提前配置用户级npm路径即可规避权限类启动问题。
- 所有后台启动的服务必须加端口/健康检查逻辑,禁止启动后直接执行业务步骤。
- 如果使用Appium 1.x版本,可去掉配置中
appium driver install xcuitest步骤,1.x版本默认内置iOS驱动。 - 如果测试代码已经适配Appium 2.x的
/基础路径,可以去掉启动参数中的--base-path /wd/hub配置。
内容的提问来源于stack exchange,提问作者Naseem
相关产品推荐
相关产品推荐

