这是一个系列文章,完整的合集链接:Appium 开发环境搭建合集

2015/2/25 update:
由于 testerhome/appium 已更新到最新版本,故把 更新代码库部分移到 Q&A 中。

2015/2/24 update:
把标题改为 Appium 开发环境搭建(1)-- 配置源码运行环境,同时微调了格式,以配合后续文章。

之前加入了 doctorq 的开源项目,今天提前配置一下 testerhome/appium 的源码运行环境。过程中发现有一些地方官方文档没有提到,在此分享一下配置过程。
PS:这是我的第一个贴子,有些地方写得不对或不够清晰请跟贴说明,我会立即更正。

1. 下载代码库

git clone https://github.com/testerhome/appium.git

然后运行此命令时所在的目录会出现一个appium文件夹。进入文件夹:

cd appium

3. 根据官方介绍配置从源码运行 appium 的环境(ios, android, seledroid)

参考资料:https://github.com/appium/appium/blob/master/docs/en/contributing-to-appium/appium-from-source.md
注意:我的配置环境为 Mac OS X 10.10.1。根据官方要求,配置过程中除非官方说明,否则尽量不要使用sudo命令。这里遇到的错误基本都和系统当前配置有关。可能有些人会遇到,有些人不会,请大家按照需要参考。

3.1 运行appium目录下的reset.sh 进行环境配置。

这个脚本进行了各个主要运行环境(ios, android, selendroid)的重置和更新,例如下载需要用到的 npm 包、安装 selendroid 等。
如果运行出错就加上--verbose参数再跑,看是哪里出错。

运行过程中我出现了几次错误,我把我遇到的错误信息和解决方案放在了文章末尾。大家可以参考一下(这里的信息都是用了--verbose后才会显示的).
另外,appium 官方有个地方也有说明其他常见错误及解决方案:https://github.com/appium/appium/blob/3f0aee727bd320377b63bbc57ab4b3fb591260c4/docs/en/appium-setup/troubleshooting.md
如果用上面的办法还是解决不了,可以去 github报个 issue来让 appium 团队帮忙寻找解决方案。

3.2(仅针对 ios)运行sudo ./bin/authorize-ios.js配置 ios 的认证环境(用来让 ios 不认为 appium 安装的应用有安全问题)。

$ sudo ./bin/authorize-ios.js
Password:
Enabling DevToolsSecurity
Updating security db for developer access
Granting access to built-in simulator apps
Authorization successful

3.3 使用node .运行 appium server:

$ node .
info: Welcome to Appium v1.3.5 (REV 80453f682c18c32377bdf5664533e4df69a62770)
info: Appium REST http interface listener started on 0.0.0.0:4723
info: Console LogLevel: debug

至此,从源码运行 appium 的环境完成了。此时运行的 appium 就是从源码运行的了。如果是 debug 的话,这样基本足够了。但对于开发来说,但这只是配置开发环境的第一步(官方文档里的Setting up Appium from Source部分),后面还有Hacking on AppiumHacking with Appium for iOS, Hacking with Appium for Android来配置开发环境,以及Running TestsRunning individual tests来执行测试。后面我会根据官方文档(https://github.com/appium/appium/blob/master/docs/en/contributing-to-appium/appium-from-source.md)配置下去,如果有遇到官方文档内没有提到的问题,我会另外开贴来帮助大家处理这些问题。

Q&A

更新代码库

通过 Fork 出来的代码库都有可能存在和源代码库不一致的情况。在此简述一下如何更新代码库。
参考资料:https://help.github.com/articles/syncing-a-fork/

$ git fetch git fetch https://github.com/appium/appium.git
git fetch https://github.com/appium/appium.git
remote: Counting objects: 6600, done.
remote: Compressing objects: 100% (2708/2708), done.
remote: Total 6600 (delta 4470), reused 5589 (delta 3679)
Receiving objects: 100% (6600/6600), 15.70 MiB | 260.00 KiB/s, done.
Resolving deltas: 100% (4470/4470), done.
From https://github.com/appium/appium
 * branch            HEAD       -> FETCH_HEAD

$ git checkout master
Warning: you are leaving 1006 commits behind, not connected to
any of your branches:

  80453f6 getting rid of old ci code, use the old-travis-ci branch for reference
  6c8eade Merge pull request #4526 from appium/v1.3.5-branch
  a124a15 clarified garbled changelog text
  634d19b fixed changelog
 ... and 1002 more.

If you want to keep them by creating a new branch, this may be a good time
to do so with:

 git branch new_branch_name 80453f6

Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.


$ git merge FETCH_HEAD
Updating 99794ad..80453f6
Fast-forward
 .gitignore                                         |   21 +-
 .gitmodules                                        |   15 +
 .jscs.json => .jscsrc                              |    8 +-
 .jshintignore                                      |    5 +
 .jshintrc                                          |    2 +-
 .travis.yml                                        |   39 -
 CHANGELOG.txt                                      |  368 ++++-
 CONTRIBUTING.md                                    |  147 +-
 Gruntfile.js                                       |   69 +-
 README.md                                          |   86 +-
 ...
 create mode 100644 test/functional/selendroid/shutdown-specs.js
 create mode 100644 test/functional/selendroid/webview-auto-specs.js
 create mode 100644 test/helpers/sim-udid.js
 create mode 100755 test/tools/prepare-tap.js
 create mode 100644 test/unit/ios-device-specs.js
 create mode 100644 trigger.txt

查看代码库更新情况:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 1006 commits.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean

注意:这里的同步仅仅更新了你的本地代码库,github 上的代码库还是旧的。需要使用git push命令才会把这个变更更新到远程代码库里。

运行./reset.sh过程出现的故障及解决方案

npm ERR! Error: EACCES, mkdir '/Users/hengjiechen/.npm/gulp-util/3.0.3'
npm ERR! { [Error: EACCES, mkdir '/Users/hengjiechen/.npm/gulp-util/3.0.3']
npm ERR! errno: 3,
npm ERR! code: 'EACCES',
npm ERR! path: '/Users/hengjiechen/.npm/gulp-util/3.0.3',
npm ERR! parent: 'appium' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.

npm ERR! Please include the following file with any support request:
npm ERR! /Users/hengjiechen/Develop/appiumSourceCode/appium/npm-debug.log
---- FAILURE: reset.sh exited with status 1 ----

**原因分析:**之前用管理员权限安装过npm,或者某些npm包用了管理员权限来安装。这里千万不要参照错误提示用管理员执行,否则appium就装不下去了。
**解决方案:**
卸载npm,删除`~/.npm`文件夹(部分目录没权限就用`sudo`来删),然后用`brew install npm`重新安装。安装后再运行`./reset.sh --verbose`(`brew`命令是`homebrew`的命令,提示没找到命令的请安装[homebrew]。不能用node官方安装程序来装)

*  Warning: Command failed: /bin/sh: mvn: command not found

...
RESETTING SELENDROID

/bin/sh: mvn: command not found

Warning: Command failed: /bin/sh: mvn: command not found
Use --force to continue.

Aborted due to warnings.
---- FAILURE: reset.sh exited with status 1 ----

**原因分析**:没找到mvn命令。我没有装`maven`。
**解决方案**:参考下一个问题,使用以下命令安装`maven`

brew install homebrew/versions/maven31
sudo ln -s /usr/local/Cellar/maven31/3.1.1 /usr/local/Cellar/maven/
brew switch maven 3.1.1


*  Warning: Command failed: Exception in thread "pool-2-thread-1" java.lang.NoClassDefFoundError: org/eclipse/aether/spi/connector/Transfer$State

...
constituent[38]: file:/usr/local/Cellar/maven/3.2.5/libexec/lib/wagon-http-shared-2.8.jar
constituent[39]: file:/usr/local/Cellar/maven/3.2.5/libexec/lib/wagon-provider-api-2.8.jar

constituent[40]: file:/usr/local/Cellar/maven/3.2.5/libexec/conf/logging/

Exception in thread "pool-2-thread-1" java.lang.NoClassDefFoundError: org/eclipse/aether/spi/connector/Transfer$State
at org.eclipse.aether.connector.wagon.WagonRepositoryConnector$GetTask.run(WagonRepositoryConnector.java:608)
at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:67)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
...
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:247)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239)
... 5 more
Use --force to continue.

Aborted due to warnings.
---- FAILURE: reset.sh exited with status 1 ----

**原因分析**:这是安装Selendroid时出错了,错误信息表示是找不到class的声明。这个只能求助google了。
**解决方案**:google后找到<https://github.com/appium/appium/issues/4490>,根据里面的解决方案使用下面命令修复:

brew install homebrew/versions/maven31
sudo ln -s /usr/local/Cellar/maven31/3.1.1 /usr/local/Cellar/maven/
brew switch maven 3.1.1


*  [ERROR] Failed to execute goal com.jayway.maven.plugins.android.generation2:android-maven-plugin:3.8.2:generate-sources (default-generate-sources) on project android-driver-app

...
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.jayway.maven.plugins.android.generation2:android-maven-plugin:3.8.2:generate-sources (default-generate-sources) on project android-driver-app: Execution default-generate-sources of goal com.jayway.maven.plugins.android.generation2:android-maven-plugin:3.8.2:generate-sources failed: Invalid SDK: Platform/API level 16 not available. This command should give you all you need:
[ERROR] /Applications/adt-bundle-mac-x86_64-20140702/sdk/tools/android update sdk --no-ui --obsolete --force
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn -rf :android-driver-app

Warning: Command failed: Use --force to continue.

Aborted due to warnings.
---- FAILURE: reset.sh exited with status 1 ----

**原因分析**:大致意思是没有找到Android sdk里的`Platform/API level 16`。官方文档提到配置seledroid的话需要用到level 16的API。
**解决方案**:装上level 16的API。
![](/photo/2015/5676739fe3196bfa8d18de749d7f5778.png)

*  Warning: Command failed: Feb 14, 2015 3:05:20 PM org.apache.maven.wagon.providers.http.httpclient.impl.client.DefaultRequestDirector tryExecute

[INFO] Compiling 172 source files to /Users/hengjiechen/Develop/appiumSourceCode/appium/submodules/selendroid/selendroid-server/target/classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] Failure executing javac, but could not parse the error:

The system is out of resources.
Consult the following stack trace for details.
java.lang.StackOverflowError
...
INFO: Retrying request
Feb 14, 2015 3:05:20 PM org.apache.maven.wagon.providers.http.httpclient.impl.client.DefaultRequestDirector tryExecute
INFO: Retrying request

Warning: Command failed: Feb 14, 2015 3:05:20 PM org.apache.maven.wagon.providers.http.httpclient.impl.client.DefaultRequestDirector tryExecute
INFO: I/O exception (java.net.SocketException) caught when processing request: Connection reset
Feb 14, 2015 3:05:20 PM org.apache.maven.wagon.providers.http.httpclient.impl.client.DefaultRequestDirector tryExecute
INFO: I/O exception (java.net.SocketException) caught when processing request: Connection reset
Feb 14, 2015 3:05:20 PM org.apache.maven.wagon.providers.http.httpclient.impl.client.DefaultRequestDirector tryExecute
INFO: Retrying request
Feb 14, 2015 3:05:20 PM org.apache.maven.wagon.providers.http.httpclient.impl.client.DefaultRequestDirector tryExecute
INFO: Retrying request
Use --force to continue.

Aborted due to warnings.
---- FAILURE: reset.sh exited with status 1 ----

**原因分析**:这个原因应该是编译器暂存空间不足导致的(StackOverflowError)。
**解决方案**:运行下面的命令加大暂存空间:

export MAVEN_OPTS="-Xms1024m -Xmx2048m -Xss2048k"





↙↙↙阅读原文可查看相关链接,并与作者交流