Appium + Mac + ios 实现UI自动化遇到的一个坑(已解决)

遇到的坑

按照appium-doctor的提示,安装好所缺少的各种组件。实际运行Appiuminspector时,参数都输入正确,但是Appium一直提示三个问题:

  1. idevice_id没有安装。具体提示为:

    [XCUITest] The ‘idevice_id’ program is not installed. If you are running a real device test it is necessary. Install with ‘brew install libimobiledevice --HEAD’
    idevice_id找不到

  2. ios-deploy 无法使用。具体提示为:

    [MJSONWP] Encountered internal error running command: Error: Could not initialize ios-deploy make sure it is installed (npm install -g ios-deploy) and works on your system.
    ios-deploy无法使用

  3. carthage 可执行文件找不到。具体提示为:

    Error: Carthage binary is not found. Install using brew install carthage if it is not installed and make sure the root folder, where carthage binary is installed, is present in PATH environment variable. The current PATH value: ‘/usr/bin:/bin:/usr/sbin:/sbin’

    这个地方不好复现,所以就不放截图了。

解决思路

本节记录下这个坑的解决思路,不想看的可以直接往下翻,看 解决步骤。

这三个命令其实都已经安稳地躺在/usr/local/bin目录下了。而且PATH变量是没问题的,但Appium就是调用不到,神奇。

这三个问题是依次出现的,一开始只是提示了第一个问题。

针对第一个问题,根据Appium的错误提示文本,我猜测这些错误文本应该是硬编码到Appium执行文件中的。恰好Appium是基于JS写的,可以直接查看对应的脚本文件。

经过搜索得到MAC电脑上,Appium使用的脚本文件都放在/Applications/Appium.app/Contents/Resources/app/node_modules目录下。所以直接使用grep搜索错误文本。具体的命令为grep -r idevice_id /Applications/Appium.app/Contents/Resources/app/node_modules/*,由此定位到目录下的appium/node_modules/appium-xcuitest-driver/build/lib/real-device-management.js就是输出错误文本的位置。对应的脚本代码如下图所示。
Appium + Mac + ios 实现UI自动化遇到的一个坑(已解决)_第1张图片
可以看到这里是直接通过进程调用了 idevice_id 命令来获取其输出。既然它找不到,那就直接把完整的命令地址放在这里。也就是将这里红圈处的 idevice_id 改成 /usr/local/bin/idevice_id。保存文件后,重启Appium inspectorAppium已经可以正常执行idevice_id

第二个问题随之冒了出来。用同样的方法解决之。

但第三个问题又冒了出来,这时候有点不对劲了。每个命令都手动修改下,得多麻烦。
不过第三个问题的提示文本有个地方给出了脚本执行时的PATH变量,

The current PATH value: ‘/usr/bin:/bin:/usr/sbin:/sbin’

这明显不对啊,Appium 使用到的命令都放在 /usr/local/bin目录下。PATH的值应该包含/usr/local/bin才对,但这里却没包含,估计问题就是出在这了。这里理论上来说是有两个解决办法的:一个是将用到的可执行文件软链接到/usr/bin目录下。另一个是找到为什么脚本执行时获取的PATH变量和系统中的不一样。

经过测试证明这两条路都是可行的。第一种方法比较直白,就不多说了。说一下第二种方法的思路。

经过代码追踪,发现脚本运行时的PATH变量是在 /Applications/Appium.app/Contents/Resources/app/node_modules/fix-path/index.js 中获取的。脚本中包含下面这段代码:
Appium + Mac + ios 实现UI自动化遇到的一个坑(已解决)_第2张图片
process.env.PATH 变量保存了脚本运行时PATH的实际内容。可以看到这个变量的内容是 shellPath.sync() 函数的输出或者字符串列表的拼接值。而从Appium的运行结果来看,shellPath.sync() 的输出就是 '/usr/bin:/bin:/usr/sbin:/sbin',所以这里可以将 || 改成 +,将这两个结果拼接起来。这样脚本运行时的PATH变量就会包含 /usr/local/bin

解决步骤

一共有两种解决办法。大家随意挑一种吧

第一种

由于Mac默认使用了一种机制来限制对/usr/bin目录的修改,即使你是管理员也不能修改。所以需要先关闭这种机制。

  1. 按照 去除/usr/bin目录修改限制 的方法去除修改限制。
  2. 对使用到的每个命令建立软链接。
    idevice_id为例,命令行输入 ln -s /usr/local/bin/idevice_id /usr/bin/idevice_id即可。

第二种

打开 /Applications/Appium.app/Contents/Resources/app/node_modules/fix-path/index.js,将代码段

process.env.PATH = shellPath.sync() || [
                './node_modules/.bin',
                '/.nodebrew/current/bin',
                '/usr/local/bin',
                process.env.PATH
        ].join(':');

改成

process.env.PATH = shellPath.sync() + [
                './node_modules/.bin',
                '/.nodebrew/current/bin',
                '/usr/local/bin',
                process.env.PATH
        ].join(':');

保存后重启 Appium inspector即可正常运行。

你可能感兴趣的:(杂技)