Appium里面怎么实现 左右滑动苹果手机屏幕滑动不了

客户端类库列表及Appium服务端支持
这些类库封装了标准Selenium客户端类库,为用户提供所有常见的 格式selenium命令以及额外的移动设备控制相关的命令,如多点触控手势和屏幕朝向。
Appium客户端类库实现了(一个标准协议的官方扩展草稿)和(一个传输不可预知的自动化协议,该协议定义了MultiAction 接口)的元素。
Appium 服务端定义了官方协议的扩展,为Appium 用户提供了方便的接口来执行各种设备动作,例如在测试过程中安装/卸载app。这就是为什么我们需要Appium 特定的客户端,而不是通用的Selenium 客户端。当然,Appium 客户端类库只是增加了一些功能,而实际上这些功能就是简单的扩展了Selenium 客户端,所以他们仍然可以用来运行通用的selenium会话。
Github版本库以及安装指南
JavaScript (Node.js)
Objective C
RobotFramework
Appium 介绍
Appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生应用,web 应用和混合应用。
所谓的“移动原生应用”是指那些用 iOS 或者 Android SDK 写的应用。所谓的“移动 web 应用”是指使用移动浏览器访问的应用(Appium 支持 iOS 上的 Safari 和 Android 上的 Chrome)。所谓的“混合应用”是指原生代码封装网页视图——原生代码和 web 内容交互。比如,像 ,可以帮助开发者使用网页技术开发应用,然后用原生代码封装,这些就是混合应用。
重要的是,Appium 是一个跨平台的工具:它允许测试人员在不同的平台(iOS,Android)使用同一套API来写自动化测试脚本,这样大大增加了 iOS 和 Android 测试套件间代码的复用性。
想知道 Appium 如何支持平台,版本和自动化形态的详细信息,请参见。
Appium 的理念
为了满足移动自动化需求,Appium 遵循着一种哲学,重点体现于以下4个需求:
你无需为了自动化,而重新编译或者修改你的应用。
你不必局限于某种语言或者框架来写和运行测试脚本。
一个移动自动化的框架不应该在接口上重复造轮子。(移动自动化的接口应该统一)
无论是精神上,还是名义上,都必须开源。
Appium 设计
那么 Appium 架构是如何实现这个哲学呢?为了满足第一条,Appium 真正的工作引擎其实是第三方自动化框架。这样,我们就不需在你的应用里植入 Appium 相关或者第三方的代码。这意味着你测试使用的应用与最终发布的应用并无二致。我们使用以下的第三方框架:
iOS: 苹果的
Android 4.2+: Google’s
Android 2.3+: Google’s . (Instrumentation由单独的项目提供支持 )
为了满足第二点,我们把这些第三方框架封装成一套 API, API.WebDriver(也就是 “Selenium WebDriver”) 指定了客户端到服务端的协议。
(参见 )。使用这种客户端-服务端的架构,我们可以使用任何语言来编写客户端,向服务端发送恰当的 HTTP 请求。
目前已经实现了大多数流行语言版本的客户端,这意味着你可以使用任何测试套件或者测试框架。客户端库就是简单的HTTP 客户,可以以任何你喜欢的方式潜入你的代码。换句话说,Appium 和 WebDriver 客户端不是技术意义上的“测试框架”,而是“自动化库”。你可以在你的测试环境中随意使用这些自动化库!
事实上 WebDriver 已经成为 web 浏览器自动化的标准,也成了 W3C 的标准 —— 。我们又何必为移动做一个完全不同的呢?所以我们扩充了,在原有的基础上添加移动自动化相关的 API 方法,这也满足了第三条理念。
第四条就不用说了,。
Appium 概念
Appium 的核心是一个 web 服务器,它提供了一套 REST 的接口。它收到客户端的连接,监听到命令,接着在移动设备上执行这些命令,然后将执行结果放在 HTTP响应中返还给客户端。事实上,这种客户端/服务端的架构给予了许多的可能性:比如我们可以使用任何实现了该客户端的语言来写我们的测试代码。比如我们可以把服务端放在不同
的机器上。比如我们可以只写测试代码,然后使用像
这样的云服务来解释命令。
自动化始终围绕一个session进行,客户端初始化一个seesion(会话)来与服务端交互,不同的语言有不同的实现方式,但是他们最终都是发送为一个POST请求给服务端,请求中包含一个JSON对象,被称作“desired capabilities”。此时,服务端就会开启一个自动化的 session,然后返回一个 session ID,session ID将会被用户发送后续的命令。
Desired Capabilities
Desired capabilities 是一些键值对的集合 (比如,一个 map 或者 hash),客户端将这些键值对发给服务端,告诉服务端我们想要怎么测试。比如,我们可以把platformName capability 设置为 iOS,告诉 Appium 服务端,我们想要一个iOS 的 session,而不是一个 Android 的。我们也可以设置 safariAllowPopups capability 为 true,确保在 Safari 自动化 session 中,我们可以使用 javascript 来打开新窗口。参见 ,查看完整的 capabilities 列表。
Appium Server
Appium server 是用 Node.js 写的。我们可以用源码编译或者从 NPM 直接安装。
Appium 服务端
Appium 服务端有很多语言库 Java, Ruby, Python, PHP, JavaScript 和 C#,这些库都实现了
Appium 对 WebDriver 协议的扩展。当使用 Appium 的时候,你只需使用这些库代替常规的 WebDriver 库就可以了。
你可以从看到所有的库的列表。
我们提供了 GUI 封装的 Appium 服务端下载,它封装了运行 Appium服务端的所有依赖,而不需要担心怎样安装Node.js。其中还包括一个Inspector工具,可以帮助你检查应用的界面层级,这样写测试用例时更方便。
Getting Started
恭喜!你现在有足够的知识来使用 Appium 了。 来我们回到
继续了解更加
细节的需求和指南。
Setting up Appium
Intel(R) 硬件加速器管理
如果你发现android模拟器太慢, 并且你的系统运行在Intel(R) 的cpu上. 那么你可以尝试下HAXM, HAXM能够让你充分利用硬件虚拟化技术来加速android模拟器。
要安装HAXM, 你可以打开Android SDK Manager, 你可以在Extras中发现这个安装选项;
你可以在找到所有相关的文档;
这将需要x86的模拟镜像;
利用Intel的包来安装HAXM; Android SDK Manager有时候会安装不成功,这主要取决于你安装的版本是否兼容。
Android Setup
使用前,你需要安装node.js(版本大于等于0.10)。 请参照 。
当node.js安装成功后,请安装 。
运行’android’ tool(位于SDK,tool文件目录下)。
运行’android’ tool 来安装大于等于Level 17的API。
(如果你想从Appium的源码来运行,可在真机或者模拟器上用
来编译bootstrap jar包)。
最后,将环境变量$ANDROID_HOME设置为 Android SDK 的路径。例如,如果你将Android SDK 解压到 /usr/local/adt/,你需要把这个路径加到你的shell环境变量中去:
export ANDROID_HOME=”/usr/local/adt/sdk”
现在就可以启动Appium了!如果你在源码中运行Appium请运行
./reset.sh --android 版本从Appium checkout会安装所有的依赖。
老版本的额外安装
当android的版本是2.3到4.1的时候,appium用的是selendroid。 当它检测到时低版本时,它会自动应用Selendroid。但是需要配置一些额外的设置如果从source运行。
或更新 (mvn)
运行 ./reset.sh --selendroid 从checkout的Appium源码
(运行Appium Android 测试)
在Linux上运行,启动一个API大于等于level17的AVD。 在源文件目录下运行 (appium) 在安装好 NPM, 或者 node。如果你选择的是从源代码方式运行。
来了解所有命令和参数。
Android 加速模拟器需要存在,它有自己的局限性,如果想了解更多,请看这里
如果你想运行任何Appium的测试,或者任何强大的命令,确保你的 hw.battery=yes 在 AVD’s config.ini文件中。
Selendroid 需要你APP中的如下权限:
&uses-permission android:name="android.**permission.INTERNET"/&,
如果你在使用selendroid或者低版本的android(如版本2.3到4.1),请确保你的App已设置internet权限。
部署iOS app 到手机上
准备在真机上执行appium测试, 需要如下准备:
用特殊的设备参数来构建app
使用 , 这是一个第三方程序,可以用来部署你构建的app到手机上
Xcodebuild 命令的参数:
新的参数运行指定设置. 参考 :
xcodebuild [-project projectname] [-target targetname ...]
[-configuration configurationname] [-sdk [sdkfullpath | sdkname]]
[buildaction ...] [setting=value ...] [-userdefault=value ...]
这有一个资料来参考可用的
CODE_SIGN_IDENTITY (Code Signing Identity)
介绍: 标识符,指定一个签名。
例如: iPhone Developer
PROVISIONING_PROFILE 已经从可用的的命令中消失了,但还是有必要设置的。
在xcodebuild命令中设置 “CODE_SIGN_IDENTITY” & “PROVISIONING_PROFILE”:
xcodebuild -sdk &iphoneos& -target &target_name& -configuration &Debug& CODE_SIGN_IDENTITY="iPhone Developer: Mister Smith" PROVISIONING_PROFILE="XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX"
成功的话, app会构建到如下目录 &app_dir&/build/&configuration&-iphoneos/&app_name&.app
用Fruitstrap进行部署
clone一个fruitstrap的fork版本在 ,这个已经不再维护. 已确认该fork可用, 但是其它的据说也可用。
clone成功的话, 执行 make fruitstrap
然后, 然后复制生成的 fruitstrap到app的所在的目录或上级目录下。
运行fruitstrap 通过输入以下命令 (命令是否可用依赖于你fork的 fruitstrap):
./fruitstrap -d -b &PATH_TO_APP& -i &Device_UDID&
如果是为了持续集成,你可以发现很有用的方法来记录fruitstrap命令行和日志文件中的记录, 像这样:
./fruitstrap -d -b &PATH_TO_APP& -i &Device_UDID& 2&&1 | tee fruit.out
在node服务启动前fruitstrap进行需要被结束, 一个方法是扫描fruitstrap的输出来得知app完成启动。 有一个有效的方法是通过一个Rakefile 和一个 go_device.sh 脚本:
bundle exec rake ci:fruit_deploy_app | do
echo "$line" | grep "text to identify successful launch"
if [ $? = 0 ]
echo "App finished launching: $line"
kill -9 `ps -aef | grep fruitstrap | grep -v grep | awk '{print $2}'`
一旦fruitstrap的进程被结束, node 服务就可以启动并且appium测试可以被执行!
Android并发测试
Appium提供了在一台设备上启动多个Android会话的方案,而这个方案需要你输入不同的指令来启动多个Appium服务来实现。
启动多个Android会话的重要指令包括:
-p Appium的主要端口
-bp Appium bootstrap端口
--chromedriver-port chromedriver端口(当使用了webviews或者chrome)
--selendroid-port selendroid端口(当使用了selendroid)
更多参数的解释详见 。
如果我们有两台设备,设备ID分别为4,我们应该用下面的命令启动来两个不同的Appium服务:
node . -p 4492 -bp 2251
node . -p 4491
-bp 2252 -U 43364
只要你的Appium和Appium bootstrap端口介于0和65536即可,并且保证是两个不同的端口以便两个Appium服务不会监听相同的端口。确认你的-u参数绑定正确的设备ID。这可以让Appium知道连接哪台设备,所以参数一定要准确。
如果你用了chromedriver或selendroid,不同的服务要设置不同的端口。
iOS并发测试
不幸的是,IOS不能进行本地并发测试。跟Android不一样,IOS在同一时间只能启动一个版本的模拟器来运行多个测试。
如果你想在IOS上进行并发测试,你需要用到Sauce。只需上传你的Appium测试脚本到Sauce,它就可以按照你的设置执行多个IOS或Android的并发测试。在Sauce上执行测试的更多信息,详见。
Appium支持的平台
Appium支持很多的运行平台和测试方式(包括原生、混合应用、内嵌浏览器、真机、模拟器等)。这篇文档主要用来让大家明确在使用
Appimu的时候支持的平台版本和上述测试方式的必备条件。
iOS平台支持
请移步到 。这里介绍了在iOS系统下使用Appium的必备条件和安装说明。
版本号:6.1,7.0,以及7.1。
支持设备:iPhone模拟器,iPad模拟器以及iPhones和iPads真机。
是否支持原生应用:支持。同时支持模拟器中调试应用版本和正确签名的真机ipa。其他相关支持由苹果的框架提供。
是否支持内置移动浏览器:支持。Safari浏览器已经通过测试。对于真机,则需要安装调试工具ios-webkit-remote-debugger。很遗憾,对于Safari的原生界面的自动化是不支持的。更多信息请移步至 。
是否支持混合应用:支持。同样对于真机需要安装调试工具ios-webkit-remote-debugger,更多详情请移步至 查看详情。
是否支持在同一个session中执行多个应用的自动化:不支持。
是否支持同时再多个设备上执行自动化:不支持。
是否支持第三方提供应用:只支持在模拟器上有限的第三方应用(例如:喜好设置、地图等)。
是否支持自定义的、非标准UI控件的自动化:仅支持很少一部分。最好对控件添加可识别信息,以方便对元素进行一些基础的自动化操作。
Android平台支持
请移步至 ,,或者 获得在不同操作系统下android平台对appium的支持和安装配置文档。
支持版本:android 2.3平台及以上。
android 4.2平台及以上通过Appium自有的类库支持。默认在自动化后台。
从android 2.3到4.3平台,Appium是通过绑定,实现自动化测试的,你可以到android开发社区的。(仪表盘)中查看相关介绍。Selendroid拥有一套不同的命令行和不同的profile文件(这部分差距正在逐步缩小)。要获得在后台运行自动化的权限,需要配置automationName 组件的值为 Selendroid。
支持的设备:Android模拟器和Android真机。
是否支持原生应用:支持。
是否支持内置移动浏览器:支持(除了使用Selendroid后台运行的情况)。通过代理方式绑定到来运行自动化测试。在android4.2和4.3版本中,只有在官方版本的谷歌浏览器或者Chromium下才能运行自动化测试。伴随着android 4.4+版本的出现。自动化测试则可以运行在内置浏览器的应用程序。但是需要在测试设备环境下安装Chrome/Chromium/浏览器。请移步至 获取更多详情。
是否支持混合应用: 支持。请移步至参考相关文档。
通过默认的Appium的后台支持android 4.4以上的版本。
通过Selendroid的后台支持android 2.3以上的版本。
是否支持在同一个session中执行多个应用的自动化:支持(但是不支持使用Selendroid后台的场景)。
是否支持同时再多个设备上执行自动化:支持,。尽管Appium必须要启动另一个端口即通过添加参数的方式运行命令行,例如--port,--bootstrap-port(或者--selendroid-port)或者--chromedriver-port。更多详情请移步至。
是否支持第三方应用自动化:支持(但是不支持Selendroid后台运行的场景)。
是否支持自定义的、非标准UI控件的自动化:不支持。
Appium在真机上
Appium已经初步支持真机测试。
如果要在真机上执行测试,你将要做如下准备:
1.一个苹果的开发者ID和有效的开发者对应的配置文件和签名文件
2.一台iPad或者iPhone
你要测试的应用的源码
一台安装了XCode和XCode Command Line Developer Tools的Mac机器
Provisioning Profile
要在真机上测试就需要一个有效的iOS开发者的Distribution Certificate and Provisioning Profile。你可以在这个上面找到配置这些的相关信息
同样的,你还需要对你的应用签名,更多的信息可以查看.
你必须使用Xcode的执行按钮来安装你的应用
使用Appium运行你的测试
一旦你的设备和应用设置好了之后,你就能够用如下的命令在你的机器上执行测试:
node . -U &UDID& --app &bundle_id&
这将会启动Appium并且开始在真机上测试应用。
疑问解答思路
确认UDID已经正确的在xcode organizar或itunes中设置了。很长的字符串(20多个字符串)
0.确认你测试代码中的测试对象设备的设置
再次确认你从instruments启动你的自动化测试
确认instruments已经关闭
在 Linux 上运行 Appium
如果你在 Linux 上使用 Appium, 那么你没法使用已经构建好的 ’.app’,那是为 OS X 准备的。 另外由于 Appium 在测试 iOS 应用时 依赖 OS X 特有的库, 所以你也没有办法测试在 Linux 上测试 iOS 应用。
首先,安装版本高于或等于 0.8 的 nodejs。可以根据
进行安装。
安装好了 node.js 之后,安装 。 你会需要运行 android adb 等工具,这些工具都在 SDK 里包含了, 你要做的是配置环境变量。当然你要确保你的 API level 大于等于 17。 你也需要使用 Ant 来构建 bootstrap jar 以便 Appium 使用它来测试 Android 应用。
最后, 设置 $ANDROID_HOME 为你的 Android SDK 的路径。比如, 你将 Android SDK 解压在 /usr/local/adt/, 那你就要将如下添加到你的 .bashrc 或 .zshrc 或 .bash_profile 等 shell 配置文件中去:
export ANDROID_HOME=”/usr/local/adt/sdk
现在你可以运行 Appium 了, 在你 checkout 出来的 Appium 目录里, 运行 .reset.sh --android, 它会帮助你安装好所有的依赖。
运行 Appium
运行测试前, 你需要启动一个 API Level 大于等于 17 的 Android 模拟器或者连接一个系统是 4.1 以上的 Android 真机。然后在 Appium 目录运行
找到所有的命令行参数。
There exists a hardware accelerated emulator for android, it has it’s own
limitations. For more information you can check out this
Android 有一些硬件加速的模拟器,这些模拟器有自己的限制。你可以在
找到更多的信息。
确保你使用的 AVD 里面的 config.ini 有这条指令 hw.battery=yes。
在 Mac OS X 上使用 Appium
在 OS X 上, Appium 支持 iOS 和 Android 测试
系统配置 (iOS)
Appium 需要 Mac OS X 10.7, 推荐 10.8。 (经过测试, 10.9 也能工作。)
确保 Xcode 和 iOS SDK 都已经安装好了。 (当前 Appium 支持 Xcode 4.6.3/iOS 6.1 和 Xcode 5/iOS 7.0。 注意不推荐在基于 Xcode 5 下且低于 7.0 的 iOS 版本进行测试。 参照下篇可以获取更多信息)
你需要授权 iOS 模拟器的使用。如果你是通过 NPM 安装的 Appium,那么你可以运行 sudo authorize_ios (authorize_ios)是来自 Appium npm 包里的一个二进制执行文件。如果你是从源代码运行 Appium,那么你可以简单的使用 sudo grunt authorize。如果你使用, 那你只要用界面来操作。
如果你使用的是Xcode 6,在启动Appium之前,你需要打开模拟器,并且在你需要进行输入文字的操作之前,必须先将输入法提前调出。你可以通过点击输入区域或通过快捷键command-K来将软键盘唤出。
Xcode 6中,有一个Devices的模块(command-shift-2可唤出)。你必须确保Appium 的capabilities参数中,所使用到的deviceName要存在于Devices里。换句话说,如果capabilities中的deviceName为”iPhone 5s”,platformVersion为”8.0”,那么你必须确保Devices中要存在那么一个设备是“iOS8系统的iPhone5s”,否则Appium将不知道使用哪一个设备进行测试。
在iOS8设置中的开发者选项里面,你可以打开或关闭UIAutomation。如果你的是iOS8设备,请在运行Appium之前,确保UIAutomation是打开状态的。
使用多种 iOS SDK 进行测试
Appium 使用苹果提供的 instruments 来启动 iOS 模拟器,默认它会使用当前安装的 Xcode 和该 Xcode 下安装好的最高版本的 iOS SDK。这就意味着如果你想测试 iOS 6.1, 但是你安装了 iOS 7.0, 那么 Appium 会强制使用 7.0 的模拟器。 唯一的方法就是安装多个Xcode,然后在安装不同的 SDK。然后在启动 Appium 前,切换到你要测试的特定的版本。
另外,我们发现 Xcode 5 上的 iOS 6.1 测试,会很慢而且不稳定。所以我们推荐,如果要在 6.1 及 6.1 以下版本的 iOS 上进行测试,请使用 Xcode 4.6.3。如果要在 iOS 7.0 上测试,请使用 Xcode 5。假设我们的 Xcode 5 在 /Applications/Xcode.app, Xcode 4.6 在 /Applications/Xcode-4.6.app,我们就可以用下面的命令来切换到 Xcode 4.6 来为 iOS 6.1 测试做准备。
sudo xcode-select -switch /Applications/Xcode-4.6.app/Contents/Developer/
如果要回到 Xcode 5 的话,我们再运行一次:
sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer/
系统配置 (Android)
在Mac OSX 上运行Android项目所需要的配置,与Linux的配置方法是一致的,请参考 。
在Windows上运行Appium
如果你在windows上安装appium,你没法使用预编译专用于OS X的.app文件,你也将不能测试IOS apps,因为appium依赖OS X专用的库来支持IOS测试。这意味着你只能通过在mac上来运行IOS的app测试。这点限制挺大。
安装 0.8版本及以上, 通过官方的安装程序来安装。
安装android的sdk包,(/sdk/index.html), 运行依赖sdk中的’android’工具。并确保你安装了Level17或以上的版本api。设置ANDROID_HOME系统变量为你的Android SDK路径,并把tools platform-tools两个目录加入到系统的Path路径里。因为这里面包含有一些执行命令
安装java的JDK,并设置JAVA_HOME 变量为你的JDK目录。
或者直接使用Android Windows SDK自带的ant,地址在eclipse\plugins目录,你需要把这个目录加到你的系统PATH变量中
安装. 并且设置M2HOME和M2环境变量,把M2环境变量添加到你的系统PATH变量中。
安装. 确保你安装了windows下的Git,以便可以运行常用的command命令
现在,你已经下载安装了所有的依赖,开始运行
运行Appium
要在windows上运行测试用例,你需要先启动Android模拟器或者连接上一个API Level17以上的android真机。然后在命令行运行appium。
如果你是使用源码运行Appium的,请在你所安装的appium目录下执行node.js命令:
在windows系统下运行appium.app时,需要使用管理员权限;当你通过源码的形式运行Appium时,也需要使用管理员权限启动CMD。
在windows系统下运行Android项目时,启动Appium时请带上--no-reset或--full-reset命令。
有一个硬件加速模拟器用于android,但是它有自己的一些限制,如果你想了解更多,请参考
确保在你的AVD的config.ini中有一个配置项为hw.battery=yes
最简略的安装方式
出于对官方文档的尊重,我按照原文翻译,如下介绍我的安装心得。官方提到的一些工具,其实并不需要安装。
下面介绍我已经测试过的安装和使用过程
安装appium
安装nodejs
使用npm安装appium,npm install -g appium
运行appium
启动appium,直接运行appium 即可。
更新appium
通过npm install -g appium 来更新appium即可
如果有任何疑问,欢迎到来交流
Appium 故障排除
当你遇到问题时,请不要急着将问题提交到Github,也不用急着发到,也许你可以在本文中找到答案。
常见问题解决办法
确保你的每一个步骤都是遵循
确保你的系统配置正确。(例如:Xcode是否升级到了最新版本,Android SDK是否有设置到环境变量ANDROID_HOME中去。)
确保你的应用存放路径没有错误。
Appium.app运行出现问题的解决办法
升级Appium.app后重新打开即可解决。如果提示你不能升级,则需要重新下载Appium.app,下载地址:
通过源码启用Appium出现问题的解决办法
使用git pull拉取最新源码,确保运行的代码是当前最新版本。
针对你所自动化的平台,运行reset.sh命令:
./reset.sh
./reset.sh –ios
# ios-only
./reset.sh –android
# android-only
./reset.sh –selendroid
# selendroid-only
当你需要下载以及构建测试应用时,运行reset.sh时你需要用到--dev指令。
你也可以使用appium-doctor来自动检测你的环境依赖都是否正常。如果你是使用源码运行,则需要使用到bin/appium-doctor.js或node bin/appium-doctor.js。
当你将Android SDK升级到22后,可能出现如下错误:
{ANDROID_HOME}/tools/ant/uibuild.xml:155: SDK does not have any Build Tools installed.
这是因为在Android SDK 22中,platform 和 build 工具被分拆到他们各自的SDK管理包中去了。你需要确保你的机器上正确安装了build-tools 和 platform-tools。
Android常见问题解决办法
确保 Android 模拟器启动并运行着。
出现设备连接问题时,运行adb kill-server && adb devices是非常有效的。它能够帮助重置和连接Android设备。
请确保环境变量 ANDROID_HOME 指向的是正确的Android SDK的路径。
IOS常见问题解决方案
确保Instruments.app是关闭的。
如果你是使用模拟器运行的,请不要将真机设备连接电脑。
确保模拟器或真机中,设置里面的accessibility辅助功能是关闭状态的。
确保App是编译在当前运行的模拟器上。
确保App是编译在合适的模拟器(或真机)上,不然会出现posix spawn的报错。(比如:运行在debug模式下的模拟器)
如果你曾经用 sudo 运行过 Appium, 你需要先删除/tmp/instruments_sock, 执行sudo rm /tmp/instruments_sock。然后在不适用SUDO的情况下再次启动Appium即可。
第一次运行Appium时,需要对Instruments进行授权。不然的话会经常弹出对话框要求你输入密码。如果你从源代码运行 Appium,你只需在主分支上运行sudo grunt authorize来回避该弹窗。如果用 npm 安装的话,运行 sudo authorize_ios 即可。注意,当你每次安装了新版本的xcode,你都需要重复以上操作。
如果检查路径正确,但仍然报 iOS Simulator failed to install the application.的错误的时候,请尝试重启你的电脑。
Webview/Hybrid/Safari 应用支持
确保真机上的’Web Inspector’为打开状态。
确保打开了Safari的开发模式。(Safari - Advance Preferences- Developer menu for
simulators)
确保由client library提供的Appium命令-context能够正常得对contexts进行切换。
当你尝试打开代理的时候,出现如下错误:select_port() failed,请参考
FirefoxOS常见问题解决办法
确保 Boot-to-Gecko 模拟器启动并运行着。
确保模拟器的屏幕是亮着并无锁屏的(可能需要重启 B2G).
到社区寻求帮助
若通过上述方法你的问题依然没有得到解决,你可以:
如果你的 Appium 无法正常工作,然后错误信息不够清晰,欢迎加入 中发表你的问题,你的问题需要包括以下内容:
你是如何运行Appium的?(Appium.app, npm, source)
你使用的是什么操作系统?
你使用的是什么设备?版本是什么? (i.e. Android 4.4, or iOS 7.1)
你使用的是真机还是模拟器?
给出你得到的客户端和服务端的出错日志 (比如,”我的Python代码中报了如下错误:balabala,在Appium server中的输出内容如链接中所示”)
除了上述, 贴出 Appium 服务器端的输出也非常重要,特别是运行在 verbose 模式。这样我们可以分析诊断问题在哪里。
如果你确信你发现的是一个BUG,请到中提交一个issue,并将BUG的内容描述清楚。
如果你从 Node 官网安装的 Node,那需要你使用 sudo 运行 npm。 但这么做并不是非常理想。请尝试从
获取node 或运行brew install node来安装 。
Webview通过代理可以支持iOS真机设备,请参考
有时候, iOS 的 UI 元素在定位到之后几毫秒会突然变得无效。这会导致一个类似(null) cannot be tapped的错误。唯一的解决方法就是把finding-and-acting的代码放到 retry 块里。
如果你是通过MacPorts安装了Node和Npm,你必须确保MacPorts的bin文件夹已经被添加到环境变量PATH中去,不然Appium会出现难以找到可执行node的情况。
特定的错误
Resolution
Running reset.sh
xcodebuild: error: SDK “iphonesimulator6.1” cannot be located
安装 iPhone 6.1 SDK 或者 使用单独的 SDK 构建 待测应用 比如: grunt buildApp:UICatalog:iphonesimulator5.1
Running reset.sh
Warning: Task “setGitRev” not found. Use –force to continue.
使用git submodule update --init更新模块并再次运行reset.sh
Running reset.sh
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project selendroid-server: Compilation failure [ERROR] Failure executing javac, but could not parse the error: [ERROR] [ERROR] [ERROR] The system is out of resources. [ERROR] Consult the following stack trace for details. [ERROR] java.lang.StackOverflowError
export MAVEN_OPTS="-Xms1024m -Xmx2048m -Xss2048k"
Running ios test
[INST STDERR] aborting launch
你的应用没有正确编译在模拟器或真机上。
Running mobile safari test
error: Could not prepare mobile safari with version '7.1'
你可能需要在此运行授权脚本以保证使iOS SDK文件为可写状态。 E.g., sudo authorize_ios
Running Appium tests
Appium 客户端库
Appium 有对应以下语言的客户端库:
请注意:有些方法,比如 endTestCoverage() 目前不能提供完整支持。
只有修复, 完整的覆盖率支持才会被添加。
如果你一定要用这些方法,请先查看 Github 上关于 bindings 的文档。
driver.lock(5)
driver.lockScreen(3);
// javascript
driver.lock(3)
$this-&lock(3);
driver.LockDevice(3);
// objective c
[driver lockDeviceScreen:3];
将 app 置于后台
把当前应用放到后台去
background_app 5
driver.background_app(5)
driver.runAppInBackground(5);
// javascript
driver.backgroundApp(5)
$this-&backgroundApp(5);
driver.BackgroundApp(5);
// objective c
[driver runAppInBackground:3];
hide_keyboard
driver.hide_keyboard()
driver.hideKeyboard();
// javascript
driver.hideKeyboard()
$this-&hideKeyboard();
$this-&hideKeyboard(array('strategy' =& 'pressKey', 'key' =& 'Done'));
driver.HideKeyboard("Done");
// objective c
[driver hideKeyboard];
启动 Activity
在当前应用中打开一个 activity 或者启动一个新应用并打开一个 activity 。 只能在 Android 上使用
driver.startActivity("appPackage","com.example.android.apis", null, null);
// javascript
driver.startActivity({appPackage: 'com.example.android.apis', appActivity: '.Foo'}, cb);
driver.start_activity('com.example.android.apis', '.Foo')
start_activity app_package: 'io.appium.android.apis', app_activity: '.accessibility.AccessibilityNodeProviderActivity'
driver.StartActivity("com.example.android.apis", ".Foo");
$this-&startActivity(array("appPackage" =& "com.example.android.apis",
"appActivity" =& ".Foo"));
// objective c
[driver startActivity:@"com.example.android.apis" package:@".Foo"];
打开通知栏 (Notifications)
打开下拉通知栏 只能在 Android 上使用
driver.openNotifications();
// javascript
driver.openNotifications(cb);
driver.open_notifications()
openNotifications
driver.OpenNotifications();
$this-&openNotifications();
// objective c
[driver openNotifications];
是否已经安装
检查应用是否已经安装
is_installed? "com.example.android.apis"
driver.is_app_installed('com.example.android.apis')
driver.isAppInstalled("com.example.android.apis")
// javascript
driver.isAppInstalled("com.example.android.apis")
.then(function (isAppInstalled) { /*...*/ })
$this-&isAppInstalled('com.example.android.apis');
driver.IsAppInstalled("com.example.android.apis-");
// objective c
[driver isAppInstalled:@"com.example.android.apis-"];
安装应用到设备中去
install 'path/to/my.apk'
driver.install_app('path/to/my.apk')
driver.installApp("path/to/my.apk")
// javascript
driver.installApp("path/to/my.apk")
$this-&installApp('path/to/my.apk');
driver.InstallApp("path/to/my.apk");
// objective c
[driver installAppAtPath:@"path/to/my.apk"];
从设备中删除一个应用
remove 'com.example.android.apis'
driver.remove_app('com.example.android.apis')
driver.removeApp("com.example.android.apis")
// javascript
driver.removeApp("com.example.android.apis")
$this-&removeApp('com.example.android.apis');
driver.RemoveApp("com.example.android.apis");
// objective c
[driver removeApp:@"com.example.android.apis"];
摇晃 (Shake)
模拟设备摇晃
driver.shake()
driver.shake()
// javascript
driver.shake()
$this-&shake();
driver.ShakeDevice();
// objective c
[driver shakeDevice];
driver.close_app();
driver.closeApp()
// javascript
driver.closeApp()
$this-&closeApp();
driver.CloseApp();
// objective c
[driver closeApp];
启动 (Launch)
根据服务关键字 (desired capabilities) 启动会话 (session) 。请注意这必须在设定 autoLaunch=false 关键字时才能生效。这不是用于启动指定的 app/activities ————你可以使用 start_activity 做到这个效果————这是用来继续进行使用了 autoLaunch=false 关键字时的初始化 (Launch) 流程的。
driver.launch_app()
driver.launchApp()
// javascript
driver.launchApp()
$this-&launchApp();
driver.LaunchApp();
// objective c
[driver launchApp];
重置 (Reset)
(翻译者注:相当于卸载重装应用)
driver.reset()
driver.resetApp()
// javascript
driver.resetApp()
$this-&reset();
driver.ResetApp();
// objective c
[driver resetApp];
可用上下文 (context)
列出所有的可用上下文
翻译备注:context可以理解为 可进入的窗口 。例如,对于原生应用,可用的context和默认context均为NATIVE_APP。详情可查看
context_array = available_contexts
driver.contexts
driver.getContextHandles()
// javascript
driver.contexts().then(function (contexts) { /*...*/ })
$this-&contexts();
driver.GetContexts()
// objective c
NSArray *contexts = driver.allC
当前上下文 (context)
列出当前上下文
context = current_context
driver.current_context
driver.getContext()
// javascript
driver.currentContext().then(function (context) { /*...*/ })
$this-&context();
driver.GetContext()
// objective c
NSString *context = driver.
切换到默认的上下文 (context)
将上下文切换到默认上下文
switch_to_default_context
driver.switch_to.context(None)
driver.context();
// javascript
driver.context()
$this-&context(NULL);
driver.SetContext();
// objective c
[driver setContext:nil];
应用的字符串 (App Strings)
获取应用的字符串
strings = app_strings
driver.app_strings
driver.getAppStrings();
// javascript
driver.getAppStrings().then(function (appStrings) { /*...*/ })
$this-&appStrings();
$this-&appStrings('ru');
driver.GetAppStrings();
// objective c
[driver appStrings];
[driver appStringsForLanguage:"@ru"];
按键事件 (Key Event)
给设备发送一个按键事件
key_event 176
driver.keyevent(176)
driver.sendKeyEvent(AndroidKeyCode.HOME);
// javascript
driver.deviceKeyEvent(wd.SPECIAL_KEYS.Home)
$this-&keyEvent('176');
driver.KeyEvent("176");
// objective c
[driver triggerKeyEvent:176 metastate:0 error:&err];
当前 Activity
获取当前 activity。只能在 Android 上使用
current_activity
driver.current_activity
driver.currentActivity();
// javascript
driver.getCurrentActivity().then(function (activity) { /*...*/ })
$this-&currentActivity();
driver.GetCurrentActivity();
// objective c
[driver currentActivity];
触摸动作(TouchAction) / 多点触摸动作(MultiTouchAction)
生成触摸动作的接口。这部分文档很快将会补充更多的内容进来。
touch_action = Appium::TouchAction.new
= find_element :name, 'Buttons, Various uses of UIButton'
touch_action.press(element: element, x: 10, y: 10).perform
action = TouchAction(driver)
action.press(element=el, x=10, y=10).release().perform()
TouchAction action = new TouchAction(driver)
.press(mapview, 10, 10)
.release().
perform();
// javascript
var action = new wd.TouchAction(driver);
.tap({el: el, x: 10, y: 10})
.release();
return action.perform(); // returns a promise
$action = $this-&initiateTouchAction();
-&press(array('element' =& $el))
-&release()
-&perform();
$action1 = $this-&initiateTouchAction();
$action1-&press(array('element' =& $els[0]))
-&moveTo(array('x' =& 10, 'y' =& 0))
-&moveTo(array('x' =& 10, 'y' =& -75))
-&moveTo(array('x' =& 10, 'y' =& -600))
-&release();
$action2 = $this-&initiateTouchAction();
$action2-&press(array('element' =& $els[1]))
-&moveTo(array('x' =& 10, 'y' =& 10))
-&moveTo(array('x' =& 10, 'y' =& -300))
-&moveTo(array('x' =& 10, 'y' =& -600))
-&release();
$multiAction = $this-&initiateMultiAction();
$multiAction-&add($action1);
$multiAction-&add($action2);
$multiAction-&perform();
ITouchAction action = new TouchAction(driver);
action.Press(el, 10, 10).Release();
action.Perform ();
滑动(Swipe)
模拟用户滑动
swipe start_x: 75, start_y: 500, end_x: 75, end_y: 0, duration: 0.8
driver.swipe(start=75, starty=500, endx=75, endy=0, duration=800)
driver.swipe(75, 500, 75, 0, 0.8)
// javascript
function swipe(opts) {
var action = new wd.TouchAction(this);
.press({x: opts.startX, y: opts.startY})
.wait(opts.duration)
.moveTo({x: opts.endX, y: opts.endY})
.release();
return action.perform();
wd.addPromiseChainMethod('swipe', swipe);
return driver.swipe({ startX: 75, startY: 500,
endY: 0, duration: 800 });
$this-&swipe(75, 500, 75, 0, 800);
捏 (Pinch)
捏屏幕 (双指往内移动来缩小屏幕)
driver.pinch(element=el)
driver.pinch(element);
// javascript
function pinch(el) {
return Q.all([
el.getSize(),
el.getLocation(),
]).then(function(res) {
var size = res[0];
var loc = res[1];
var center = {
x: loc.x + size.width / 2,
y: loc.y + size.height / 2
var a1 = new wd.TouchAction(this);
a1.press({el: el, x: center.x, y:center.y - 100}).moveTo({el: el}).release();
var a2 = new wd.TouchAction(this);
a2.press({el: el, x: center.x, y: center.y + 100}).moveTo({el: el}).release();
var m = new wd.MultiAction(this);
m.add(a1, a2);
return m.perform();
}.bind(this));
wd.addPromiseChainMethod('pinch', pinch);
wd.addElementPromiseChainMethod('pinch', function() {
return this.browser.pinch(this);
return driver.pinch(el);
return el.pinch();
$this-&pinch($el);
driver.Pinch(25, 25)
放大 (Zoom)
放大屏幕 (双指往外移动来放大屏幕)
driver.zoom(element=el)
driver.zoom(element);
// javascript
function zoom(el) {
return Q.all([
this.getWindowSize(),
this.getLocation(el),
]).then(function(res) {
var size = res[0];
var loc = res[1];
var center = {
x: loc.x + size.width / 2,
y: loc.y + size.height / 2
var a1 = new wd.TouchAction(this);
a1.press({el: el}).moveTo({el: el, x: center.x, y: center.y - 100}).release();
var a2 = new wd.TouchAction(this);
a2.press({el: el}).moveTo({el: el, x: center.x, y: center.y + 100}).release();
var m = new wd.MultiAction(this);
m.add(a1, a2);
return m.perform();
}.bind(this));
wd.addPromiseChainMethod('zoom', zoom);
wd.addElementPromiseChainMethod('zoom', function() {
return this.browser.zoom(this);
return driver.zoom(el);
return el.zoom();
$this-&zoom($el);
driver.Zoom(100, 200);
滑动到 (Scroll To)
滑动到某个元素。
element = find_element :name, 'Element Name'
execute_script "mobile: scrollTo", :element =& element.ref
todo: python
WebElement element = driver.findElement(By.name("Element Name"));
HashMap&String, String& arguments = new HashMap&String, String&();
arguments.put("element", element.getId());
(JavascriptExecutor)driver.executeScript("mobile: scrollTo", arguments);
// javascript
return driver.elementByName().then(function (el) {
return driver.execute('mobile: scrollTo', {element: el.value});
$els = $this-&elements($this-&using('class name')-&value('android.widget.TextView'));
$this-&scroll($els[count($els) - 1], $els[0]);
todo: csharp
拉出文件 (Pull File)
从设备中拉出文件
pull_file 'Library/AddressBook/AddressBook.sqlitedb'
driver.pull_file('Library/AddressBook/AddressBook.sqlitedb')
driver.pullFile("Library/AddressBook/AddressBook.sqlitedb");
// javascript
driver.pullFile("Library/AddressBook/AddressBook.sqlitedb")
.then(function (base64File) { /*...*/ })
$this-&pullFile('Library/AddressBook/AddressBook.sqlitedb');
driver.PullFile("Library/AddressBook/AddressBook.sqlitedb");
推送文件(Push file)
推送文件到设备中去
data = "some data for the file"
path = "/data/local/tmp/file.txt"
push_file path, data
data = "some data for the file"
path = "/data/local/tmp/file.txt"
driver.push_file(path, data.encode('base64'))
byte[] data = Base64.encodeBase64("some data for the file".getBytes());
String path = "/data/local/tmp/file.txt";
driver.pushFile(path, data)
// javascript
driver.pushFile(path, data)
$path = 'data/local/tmp/test_push_file.txt';
$data = 'This is the contents of the file to push to the device.';
$this-&pushFile($path, base64_encode($data));
driver.PushFile("/data/local/tmp/file.txt", "some data for the file");
从这里你可以获取/设置 appium 的服务器设置。
想知道它如何工作,以及它支持哪些设置,请查看
current_settings = get_settings
update_settings someSetting: true
current_settings = driver.get_settings()
driver.update_settings({"someSetting": true})
JsonObject settings = driver.getSettings()
// java-client doesn't support setting arbitrary settings, just settings which are already provided by appium.
// So for the 'ignoreUnimportantViews' setting, the following method exists:
driver.ignoreUnimportantViews(true);
var settings = driver.settings();
browser.updateSettings({'someSetting': true});
$settings = $this-&getSettings();
$this-&updateSettings(array('cyberdelia' =& "open"));
Dictionary&String, Object&settings = driver.GetSettings();
// dotnet-driver doesn't support setting arbitrary settings, just settings which are already provided by appium.
// So for the 'ignoreUnimportantViews' setting, the following method exists:
driver.IgnoreUnimportantViews(true);
Appium 桌面应用
Appium 的桌面应用支持 OS X 和 Windows.
Appium 服务关键字
automationName
你想使用的自动化测试引擎
Appium (默认) 或 Selendroid
platformName
你要测试的手机操作系统
iOS, Android, 或 FirefoxOS
platformVersion
手机操作系统版本
例如: 7.1, 4.4
deviceName
使用的手机类型或模拟器类型
iPhone Simulator, iPad Simulator, iPhone Retina 4-inch, Android Emulator, Galaxy S4, 等。在 iOS 上,这个关键字的值必须是使用 instruments -s devices 得到的可使用的设备名称之一。在 Android 上,这个关键字目前不起作用。
.ipa or .apk文件所在的本地绝对路径或者远程路径,也可以是一个包括两者之一的.zip。 Appium会先尝试安装路径对应的应用在适当的真机或模拟器上。针对Android系统,如果你指定app-package和app-activity(具体见下面)的话,那么就可以不指定app。 会与 browserName 冲突
比如/abs/path/to/my.apk或/app.ipa
browserName
需要进行自动化测试的手机 web 浏览器名称。如果是对应用进行自动化测试,这个关键字的值应为空。
iOS 系统上可以用 ‘Safari’ ,Android 系统上可以用 ‘Chrome’, ‘Chromium’, 或 ‘Browser’。
newCommandTimeout
设置命令超时时间,单位:秒。达到超时时间仍未接收到新的命令时 Appium 会假设客户端退出然后自动结束会话。
autoLaunch
Appium是否需要自动安装和启动应用。默认值true
true, false
(Sim/Emu-only) 设定模拟器 ( simulator / emulator ) 的语言。
(Sim/Emu-only) 设定模拟器 ( simulator / emulator ) 的区域设置。
如: fr_CA
连接的物理设备的唯一设备标识
如: 1ae2g
orientation
(Sim/Emu-only) 在一个设定的方向模式中开始测试
LANDSCAPE (横向)
或 PORTRAIT (纵向)
autoWebview
直接转换到 WebView 上下文。 默认值 false、
true, false
不要在会话前重置应用状态。默认值false。
true, false
(iOS) 删除整个模拟器目录。(Android) 通过卸载——而不是清空数据——来重置应用状态。在 Android 上,这也会在会话结束后自动清除被测应用。默认值 false
true, false
Android特有
appActivity
你要从你的应用包中启动的 Android Activity 名称。它通常需要在前面添加 .
(如:使用.MainActivity 而不是 MainActivity)
MainActivity, .Settings
appPackage
你想运行的Android应用的包名
比如com.example.android.myApp, com.android.settings
appWaitActivity
你想要等待启动的 Android Activity 名称
SplashActivity
deviceReadyTimeout
设置等待一个模拟器或真机准备就绪的超时时间
androidCoverage
用于执行测试的 instrumentation 类。作为命令 adb shell am instrument -e coverage true -w 的 -w 参数。
com.my.Pkg/com.my.Pkg.instrumentation.MyInstrumentation
enablePerformanceLogging
(仅适用于 Chrome 和 webview) 开启 Chromedriver 的性能日志。 (默认 false)
true, false
androidDeviceReadyTimeout
等待设备在启动应用后准备就绪的超时时间。以秒为单位。
androidDeviceSocket
开发工具的 socket 名称。只有在被测应用是一个使用 Chromium 内核的浏览器时需要。 socket 会被浏览器打开,然后 Chromedriver 把它作为开发者工具来进行连接。
如 chrome_devtools_remote
需要启动的 AVD
(安卓虚拟设备) 名称。
avdLaunchTimeout
以毫秒为单位,等待 AVD 启动并连接到 ADB 的超时时间。(默认值 120000)
avdReadyTimeout
以毫秒为单位,等待 AVD 完成启动动画的超时时间。(默认值 120000)
启动 AVD 时需要加入的额外的参数。
如 -netfast
useKeystore
使用一个自定义的 keystore 来对 apk 进行重签名。默认值 false
true or false
keystorePath
自定义 keystore 的路径。默认: ~/.android/debug.keystore
如 /path/to.keystore
keystorePassword
自定义 keystore 的密码。
key 的别名
如 androiddebugkey
keyPassword
key 的密码
chromedriverExecutable
webdriver 可执行文件的绝对路径 (如果 Chromium 核心提供了对应的 webdriver, 应该用它代替 Appium 自带的 webdriver)
/abs/path/to/webdriver
autoWebviewTimeout
以毫秒为单位,等待 Webview 上下文激活的时间。默认值 2000
intentAction
用于启动 activity 的 intent action。 (默认值 android.intent.action.MAIN)
如 android.intent.action.MAIN, android.intent.action.VIEW
intentCategory
用于启动 activity 的 intent category。 (默认值 android.intent.category.LAUNCHER)
如 android.intent.category.LAUNCHER, android.intent.category.APP_CONTACTS
intentFlags
用于启动 activity 的标识 ( flags )
(默认值 0x)
optionalIntentArguments
用于启动 activity 的额外 intent 参数。请查看
如 --esn &EXTRA_KEY&, --ez &EXTRA_KEY& &EXTRA_BOOLEAN_VALUE&
stopAppOnReset
在使用 adb 启动应用前停止被测应用的进程 ( process ) 。如果被测应用是被另一个应用创建的,当这个参数被设定为 false 时,允许另一个应用的进程在使用 adb 启动被测应用时继续存活。默认值 true
true 或 false
unicodeKeyboard
使用 Unicode 输入法。默认值 false
true 或 false
resetKeyboard
在设定了 unicodeKeyboard 关键字的 Unicode 测试结束后,重置输入法到原有状态。如果单独使用,将会被忽略。默认值 false
true 或 false
跳过检查和对应用进行 debug 签名的步骤。只能在使用 UiAutomator 时使用,使用 selendroid 是不行。默认值 false
true 或 false
ignoreUnimportantViews
调用 uiautomator 的函数 setCompressedLayoutHierarchy()。由于 Accessibility 命令在忽略部分元素的情况下执行速度会加快,这个关键字能加快测试执行的速度。被忽略的元素将不能够被找到,因此这个关键字同时也被实现成可以随时改变的 *设置 ( settings ) * 。默认值 false
true 或 false
calendarFormat
(Sim-only) 为iOS的模拟器设置日历格式
如 gregorian (公历)
被测应用的 bundle ID 。用于在真实设备中启动测试,也用于使用其他需要 bundle ID 的关键字启动测试。在使用 bundle ID 在真实设备上执行测试时,你可以不提供 app 关键字,但你必须提供 udid 。
如 io.appium.TestApp
连接的真实设备的唯一设备编号 ( Unique device identifier )
launchTimeout
以毫秒为单位,在 Appium 运行失败之前设置一个等待 instruments 的时间
比如: 20000
locationServicesEnabled
(Sim-only) 强制打开或关闭定位服务。默认值是保持当前模拟器的设定
true 或 false
locationServicesAuthorized
(Sim-only) 通过修改 plist 文件设定是否允许应用使用定位服务,从而避免定位服务的警告出现。默认值是保持当前模拟器的设定。请注意在使用这个关键字时,你同时需要使用 bundleId 关键字来发送你的应用的 bundle ID。
true 或者 false
autoAcceptAlerts
当 iOS 的个人信息访问警告 (如 位置、联系人、图片) 出现时,自动选择接受( Accept )。默认值 false。
true 或者 false
autoDismissAlerts
当 iOS 的个人信息访问警告 (如 位置、联系人、图片) 出现时,自动选择不接受( Dismiss )。默认值 false。
true 或者 false
nativeInstrumentsLib
使用原生 intruments 库 (即关闭 instruments-without-delay )
true 或者 false
nativeWebTap
(Sim-only) 在Safari中允许“真实的”,非基于 javascript 的 web 点击 (tap) 。 默认值: false。注意:取决于 viewport 大小/比例, 点击操作不一定能精确地点中对应的元素。
true 或者 false
safariInitialUrl
(Sim-only) (&= 8.1) 初始化 safari 的时使用的地址。默认是一个本地的欢迎页面
safariAllowPopups
(Sim-only) 允许 javascript 在 Safari 中创建新窗口。默认保持模拟器当前设置。
true 或者 false
safariIgnoreFraudWarning
(Sim-only) 阻止 Safari 显示此网站可能存在风险的警告。默认保持浏览器当前设置。
true 或者 false
safariOpenLinksInBackground
(Sim-only) Safari 是否允许链接在新窗口打开。默认保持浏览器当前设置。
true 或者 false
keepKeyChains
(Sim-only) 当 Appium 会话开始/结束时是否保留存放密码存放记录 (keychains)
(库(Library)/钥匙串(Keychains))
true 或者 false
localizableStringsDir
从哪里查找本地化字符串。默认值 en.lproj
processArguments
通过 instruments 传递到 AUT 的参数
如 -myflag
interKeyDelay
以毫秒为单位,按下每一个按键之间的延迟时间。
showIOSLog
是否在 Appium 的日志中显示设备的日志。默认值 false
true 或者 false
sendKeyStrategy
输入文字到文字框的策略。模拟器默认值:oneByOne (一个接着一个) 。真实设备默认值:grouped (分组输入)
oneByOne, grouped 或 setValue
screenshotWaitTimeout
以秒为单位,生成屏幕截图的最长等待时间。默认值: 10。
waitForAppScript
用于判断 “应用是否被启动” 的 iOS 自动化脚本代码。默认情况下系统等待直到页面内容非空。结果必须是布尔类型。
例如 , target.elements().length & 0;, $.delay(5000);
元素定位与交互
Appium支持webdriver定位策略的子集
根据”class”定位(例如, UI组件类型)
根据”xpath”定位 (例如,具有一定约束的路径抽象标示, 基于XPath方式)
另外, Appium 还支持部分
的定位策略
ios uiautomation: 一个递归地、对应使用
搜索元素的字符串(iOS-only)
android uiautomator: 一个递归地、对应使用 搜索元素的字符串 (Android-only)
accessibility id: 一个递归地、使用本地Accessibility选项实现的Id/Name进行元素搜索的字符串。
存在的问题
如果遇到定位元素变得无效请联系并告知我们。我们将会努力修复
使用Appium Inspector来定位元素
(翻译备注: 这个工具目前只有Mac版本, 如果你使用的是windows, 可以使用android sdk自带的 uiautomatorviewer 工具来获得元素的位置)
Appium提供了一个灵活的工具Appium Inspector, 允许你在app运行的时候, 直接定位你正在关注的元素. 通过Appium Inspector(靠近start test按钮的小”i”按钮), 你可以通过点击预览窗口上的控件来获得它的name属性, 或者直接在UI导航窗口中定位
Appium Inspector有一个简单的布局, 全部由如下窗口组成.
UI导航器, 预览, 录制与刷新按钮, 和交互工具
启动Appium Inspector后(通过点击app右上的小”i”按钮), 你可以定位任何预览窗口中的元素. 作为测试, 我正在查找id为”show alert”的按钮
要找到这个按钮的id, 在定位预览窗口中我点击了”show alert”按钮, Appium Inspector在UI导航窗口中高亮显示了这个元素, 然后展示了刚被点击按钮的id和元素类型
iOS 谓词(Predicate)
在查看 ’-ios uiautomation’ 搜索策略时了解 谓词(Predicate) 十分必要。 有下列几种非常有用的方法:
(UIAElement) UIAElementArray.firstWithPredicate(PredicateString predicateString)
(UIAElementArray) UIAElementArray.withPredicate(PredicateString predicateString)
原生的JS搜索策略(由Apple提供)提供了更大的灵活性,并且和XPath很像。
可以通过使用多个匹配条件来准确定位某一个或某一组元素(相当于只有搜索条件与元素的计算结果为 true 时这些元素才会被认为是匹配的)。
(翻译备注:XPath 是一门用来定位 xml 文档中的元素的语言,能提供基于路径、元素属性等条件的定位策略)
appiumDriver.findElementsByIosUIAutomation("collectionViews()[0].cells().withPredicate(\"ANY staticTexts.isVisible == TRUE\")")
将只选择那些在主视图第一个 UIACollectionView 元素下的、拥有可见子元素 UIAStaticText 的 UIACollectionCell 元素。在这里, staticTexts() 和 isVisible() 分别是UIAElementArray 和 UIAElement 的子方法。 注意: UIAElementArray 序列编号从 0 开始,而不是像 Xpath 那样从 1开始
以下是所有可用的谓词(Predicate)的列表(主要取自 )
- 左边表达式等于右边表达式:
”`javascript
tableViews().cells().firstWithPredicate(“label == ‘Olivia’ ”)
same in Xpath: /UIATableView/UIATableCell
- 左边表达式大于或等于右边表达式。
- 左边表达式小于或等于右边表达式。
- 左边表达式大于右边表达式。
- 左边表达式小于右边表达式。
- 左边表达式不等于右边表达式。
- 左边表达式的值在右边表达式的两个边界值之间或等于其中一个边界值。右边表达式为一个有两个值的数组,数组的第一个值是上限,第二个值是下限(这个顺序是固定的) ,例如 1 BETWEEN { 0 , 33 }, 或者 $INPUT BETWEEN { $LOWER, $UPPER }。
在 Objective-C, 你可以创建一个自定义的 BETWEEN 谓词(Predicate),如下面的示例所示:
NSPredicate *betweenPredicate =
[NSPredicate predicateWithFormat: @"attributeName BETWEEN %@", @[@1, @10]];
这创建了一个等价于 ( ( 1 &= attributeValue ) && ( attributeValue &= 10 ) ) 的谓词
布尔值谓词
TRUEPREDICATE
- 计算结果恒等于 TRUE 。
FALSEPREDICATE
- 计算结果恒等于 FALSE。
基本的复合谓词
字符串比较
在默认情况下,字符串比较是区分大小写和音调( diacritic )的,你可以在方括号中用关键字符
c 和 d 来修改操作符以相应的指定不区分大小写和变音符号。例如 名字的开头 firstName BEGINSWITH[cd] $FIRST_NAME
(翻译备注:这里的音调是指英文字母的音调,如 "náive" 和 "naive"。如果不加关键字 d,这两个字符串会认为是不等价的。)
BEGINSWITH
- 左边的表达式以右边的表达式作为开始。
scrollViews()[3].buttons().firstWithPredicate("name BEGINSWITH 'results toggle' ")
same in Xpath: /UIAScrollView[4]/UIAButton[starts-with(@name, 'results toggle')][1]
- 左边的表达式包含右边的表达式。
tableViews()[1].cells().withPredicate("ANY collectionViews[0].buttons.name CONTAINS 'opera'")
same in Xpath: /UIATableView[2]/UIATableCell[UIACollectionView[1]/UIAButton[contains(@name, 'opera')]]
- 左边的表达式以右边的表达式作为结束。
- 左边表达式等于右边表达式: ? 和 *可作为通配符, 其中 ? 匹配 1 个字符, * 匹配 0 个或者多个字符。 在 Mac OS X v10.4, 通配符不能匹配换行符。
tableViews()[0].cells().firstWithPredicate("name LIKE '*Total: $*' ")
same in Xpath: /UIATableView[1]/UIATableCell[matches(@name, '.*Total: \$.*')][1]
- 左边表达式根据ICU v3的正则表达式风格比较,等于右边表达式 (详情请看ICU用户指南中的 )。
tableViews().firstWithPredicate("value MATCHES '.*of 7' ")
same in Xpath: /UIATableView[matches(@value, '.*of 7')][1]
ANY , SOME
- 指定匹配后续表达式的任意元素。例如 ANY children.age & 18 。
tableViews()[0].cells().firstWithPredicate("SOME staticTexts.name = 'red'").staticTexts().withName('red')
same in Xpath: /UIATableView[1]/UIATableCell[UIAStaticText/@name = 'red'][1]/UIAStaticText[@name = 'red']
- 指定匹配后续表达式的所有元素。例如 ALL children.age & 18 。
- 指定不匹配后续表达式的元素。例如 NONE children.age & 18 。 逻辑上等价于 NOT (ANY ...) 。
- 等价于 SQL 的 IN 操作,左边的表达必须出现在右边指定的集合中。例如 name IN { 'Ben', 'Melissa', 'Matthew' } 。 这个集合可以是一个数组( array ),一个列表( set ), 或者一个字典( dictionary )。当这个集合是字典时,这里使用的是它的值( value )。
array[index]
- 指定数组中特定索引处的元素。
array[FIRST]
- 指定数组中的第一个元素。
array[LAST]
- 指定数组中的最后一个元素。
array[SIZE]
- 指定数组的大小
elements()[0].tableViews()[0].cells().withPredicate("staticTexts[SIZE] & 2")
same in Xpath: /*/UIATableView/UIATableCell[count(UIAStaticText) & 2]
C语言标识符
- 任何C语言的标识符都不是保留字。
- 用来把一个保留字转义为用户标识符。
[\]{octaldigit}{3}
- 用来表示一个八进制数 ( \后面加上3位八进制数字)。
[\][xX]{hexdigit}{2}
- 用于表示十六进制数 ( \x 或 \X 后面加上2个十六进制数字)。
[\][uU]{hexdigit}{4}
- 用于表示 Unicode 编码 ( \u 或 \U 后面加上4个十六进制数字)。
文字 (Literals)
(翻译备注:Literals 在编程语言领域的意思是在代码中可以看得到的(或说可视的)那些值。例如字符串 "a",数组 [1, 2],你可以在代码中一眼看出这是一个字符串,数组还是别的数据类型并知道它的值。这一节说的就是这些值的写法)
单引号和双引号都能产生相同的结果,但他们不会匹配对方(单引号不会匹配双引号)。例如:"abc" and 'abc' 都是可识别的 ,但是 "a'b'c" 等价于a, 'b', c。
FALSE , NO
表示逻辑上的 false。
TRUE , YES
表示逻辑上的 true。
NULL , NIL
- 代表被使用的对象本身。
- 一个字符串。
- 同上,也是一个字符串。
以逗号分隔的文本数组
- 举个例子 { 'comma', 'separated', 'literal', 'array' } 。
标准的整数和小数
- 举个例子 1 , 27 , 2.71828 , 19.75 。
带有幂指数的小数
- 举个例子 9.2e-5 。
- 十六进制数的前缀, 如0x11表示十六进制数11,等同于十进制的17。
- 八进制数的前缀。
- 二进制数的前缀。
下面的都是保留字:
AND, OR, IN, NOT, ALL, ANY, SOME, NONE, LIKE, CASEINSENSITIVE, CI, MATCHES, CONTAINS, BEGINSWITH, ENDSWITH, BETWEEN, NULL, NIL, SELF, TRUE, YES, FALSE, NO, FIRST, LAST, SIZE, ANYKEY, SUBQUERY, CAST, TRUEPREDICATE, FALSEPREDICATE
Appium 谓词(predicate)帮助文档
Appium 在app.js中有
getFirstWithPredicate
getFirstWithPredicateWeighted
getAllWithPredicate
getNameContains
如下是个Ruby的例子
# Ruby example
text = 'Various uses'
predicate = "name contains[c] '#{text}' || label contains[c] '#{text}' || value contains[c] '#{text}'"
element = execute_script(%Q(au.mainApp().getFirstWithPredicate("#{predicate}");))
puts element.name # Buttons, Various uses of UIButton
自动化手机网页应用
如果你正对于如何在iOS的Safari或Android上的Chrome做网页应用的自动化感兴趣,
那么Appium能够帮助你。基本上,你可以正常的写webdriver测试,只需要把Appium当
成一个有特殊设置的selenium Server。
iOS模拟器上的Safari浏览器
首先,要确保你的Safari浏览器参数中开启了开发者模式,这样Safari的远程调试端口也会被同时打开。
不管你使用模拟器还是真机,你必须使用Appium开始之前先开启Safari。
然后设置如下显示的这些信息以便于在设备中的Safari执行测试:
// javascript
platformName: 'iOS'
, platformVersion: '7.1'
, browserName: 'Safari'
, deviceName: 'iPhone Simulator'
'platformName': 'iOS',
'platformVersion': '7.1',
'browserName': 'Safari',
'deviceName': 'iPhone Simulator'
public static $browsers = array(
'desiredCapabilities' =& array(
'platformName' =& 'iOS',
'platformVersion' =& '7.1',
'browserName' =& 'Safari',
'deviceName' =& 'iPhone Simulator'
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "7.1");
capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone Simulator");
iOS真机上的Safari浏览器
为了能够在真机上的Safari执行测试,我们使用了来启动Safari。
一旦Safari被启动,则使用来自动启动Safari的远程调试功能。
提示: 目前在ios-webkit-debug-proxy中有一个。
你必须添加信任才能开始运行ios-webkit-debug-proxy。
当你要在真机上的Safari中执行你的测试脚本之前你需要先注意以下几点:
安装并运行 ios-webkit-debug-proxy,并监听27753端口 (具体可以参考()
打开iOS真机中的 web inspector,可以在iOS6.0或更高版本中的 设置 & safari & 高级找到。
创建一个 provisioning profile 能够帮助你配置safariLauncher。
你可以前往 Apple Developers Member Center 创建一个launcher profile:
第一步: 创建一个 新的App Id 同时设置WildCard App ID这个选项置为”“
*第二步:** 为步骤1的App Id创建一个 new Development Profile 。
第三步: 选择你的 certificate(s) and device(s) 并选择下一步。
第四步: 设置profile的名称以及 generate the profile。
第五步: 下载profile并使用文本编辑器打开。
第六步: 寻找并牢记你的 UUID
现在你有了自己的profile文件,可以在终端中输入如下的命令:
$ git clone
$ cd appium
# 选项1:你可以不设置任何的参数。appium会把签名 (code signing identity) 设为'iPhone Developer'
$ ./reset.sh --ios --real-safari
# 选项2:你需要定义code signing identity并且允许xcode选择profile identity code
$ ./reset.sh --ios --real-safari --code-sign '&code signing idendity&'
# 选项3:你需要设置&code signing idendity&和&profile identity code&
$ ./reset.sh --ios --real-safari --code-sign '&code signing idendity&' --profile '&retrieved profile identity code&'
# 设置成功之后,就可以像往常一样启动服务
$ node /lib/server/main.js -U &UDID&
如果要在safari下的运行你的测试, 只需要简单的配置“browserName”为safari即可
// 配置web driver并启动webview应用
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari");
URL url = new URL("http://127.0.0.1:4723/wd/hub");
AppiumDriver driver = new AppiumDriver(url, desiredCapabilities);
// 跳转到指定页面并在该页面所以用元素id进行交互
driver.get("/test/guinea-pig");
WebElement div = driver.findElement(By.id("i_am_an_id"));
Assert.assertEquals("I am a div", div.getText()); //跳转到指定页面并在该页面所以用元素id进行交互
driver.findElement(By.id("comments")).sendKeys("My comment"); //通过id查找评论框并输入
// 关闭应用
driver.quit();
Python 范例
# 配置web driver并启动webview应用
capabilities = { 'browserName': 'Safari' }
driver = webdriver.Remote('http://localhost:4723/wd/hub', capabilities)
# 跳转到指定页面并在该页面所以用元素id进行交互
driver.get('/test/guinea-pig');
div = driver.find_element_by_id('i_am_an_id')
# 检查文本是否符合预期
assertEqual('I am a div', div.text)
# 通过id查找评论框并输入
driver.find_element_by_id('comments').send_keys('My comment')
# 关闭应用
driver.quit()
class ContextTests extends PHPUnit_Extensions_AppiumTestCase
public static $browsers = array(
'desiredCapabilities' =& array(
'platformName' =& 'iOS',
'platformVersion' =& '7.1',
'browserName' =& 'Safari',
'deviceName' =& 'iPhone Simulator'
public function testThings()
$this-&get('/test/guinea-pig');
$div = $this-&byId('i_am_an_id');
$this-&assertEquals('I am a div', $div-&text());
$this-&byId('comments')-&sendKeys('My comment');
在真机或模拟器上的Chrome执行测试
需要做的准备:
确认Chrome已经安装在了你的真机或模拟器上 (应用的包名是com.android.chrome) 。在不编译Chromium的情况下, 不可能得到模拟器上的x86版本的chrome,你可以运行一个ARM的模拟器然后从真机上获取一个Chrome的APK安装在模拟器上。
如果你是使用下载的,
或者是在运行的话,那你不需要其他额外的工作。如果你是使用源码运行,reset会下载ChromeDriver并放在build。
使用 --chromedriver-version 选项可以指定chromedriver的版本 (例如 ./reset.sh --android --chromedriver-version 2.8),
否则使用最新版。
接着,像这样设置就可以在Chrome上执行测试了:
// javascript
platformName: 'Android'
, platformVersion: '4.4'
, deviceName: 'Android Emulator'
, browserName: 'Chrome'
'platformName': 'Android',
'platformVersion': '4.4',
'deviceName': 'Android Emulator',
'browserName': 'Chrome'
public static $browsers = array(
'desiredCapabilities' =& array(
'platformName' =& 'Android',
'platformVersion' =& '4.4',
'browserName' =& 'Chrome',
'deviceName' =& 'Android Emulator'
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator");
capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Chrome");
在4.4以上的版本,你也可以用’Browser’ browserName 来对内置浏览器进行自动化。
在所有版本你都可以用’Chromium’ browserName来对Chromium进行自动化。
chromedriver故障排查
从Chrome 33开始,不再必须将设备root。在之前的版本,设备必须按要求进行root (ChromeDriver需要写 /data/local 目录来设定Chrome的命令行参数) 。
如果在版本33之前在Chrome上测试app,确保adb shell拥有设备中/data/local目录的读写权限:
$ adb shell su -c chmod 777 /data/local
更多关于chromedriver的文档详见。
调整网络设置
Selenium 的
支持一个获取和设置设备网络连接的
。这个 API 通过位掩码(bitmask)工作,把所有可能的状态用一个整型数据表示:
0 (什么都没有)
1 (飞行模式)
2 (只有Wifi)
4 (只有数据连接)
6 (开启所有网络)
翻译备注:数据链接即2g, 3g, 4g的网络连接。
很不幸,目前 Appium 在 iOS 下不支持 Selenium 的网络连接 API。
选择你想使用的设置,然后根据上面的表格发送正确的位掩码(bitmask)。
// javascript
// 设置网络连接为飞行模式
driver.setNetworkConnection(1)
// 设置网络连接为仅启用Wifi
driver.setNetworkConnection(2)
// 设置网络连接为仅启用数据连接
driver.setNetworkConnection(4)
// 设置网络连接为启用数据连接和Wifi
driver.setNetworkConnection(6)
获取网络连接设置会返回基于同样规则的位掩码,你可以将其解码来获得网络设置。
// javascript
driver.getNetworkConnection().then(function (connectionType) {
switch (connectionType) {
// 飞行模式
// 数据连接
// wifi和数据连接
准备被测应用 (iOS)
在模拟器上测试apps必须要用模拟器专用的编译器,例如使用下列的命令来编译Xcode项目:
& xcodebuild -sdk iphonesimulator6.0
这行指令在Xcode项目底下创建了一个build/Release-iphonesimulator目录,并且生成一个可以透过Appium服务器来通讯的的.app封包。
如果需要,你可以把.app 目录压缩成一个zip压缩档! Appium 会自行解压缩。让你能方便在非本地运行Appium。
准备被测应用 (Android)
用Appium去执行你的.apk档其实没什么特别需要注意的事项。如果需要,你可以把它压缩成zip压缩档。
用Appium测试你的app (iOS)
想知道如何编写测试脚本,请参照测试范例:
基本上来说,首先先确定你启动了Appium:
然后执行你的WebDriver测试脚本,脚本必须包含下列的环境参数:
javascript
// javascript
platformName: 'iOS',
platformVersion: '7.1',
deviceName: 'iPhone Simulator',
app: myApp
'platformName': 'iOS',
'platformVersion': '7.1',
'deviceName': 'iPhone Simulator',
'app': myApp
public static $browsers = array(
'desiredCapabilities' =& array(
'platformName' =& 'iOS',
'platformVersion' =& '7.1',
'deviceName' =& 'iPhone Simulator',
'app' =& $myApp
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "7.1");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone Simulator");
capabilities.setCapability(MobileCapabilityType.APP, myApp);
在这个脚本集里,myApp必须是下列其中之一:
一个模拟器编译过的.app 目录或者.zip 文件的本地绝对路径
一个包含着你的.app封包的zip档的url
appium安装根目录下的一个示例app的相对路径
在你选择的WebDriver库里,设定remote session使用上述的环境参数然后使用端口4723来连接本地服务器(或者使用你在Appium启动时所设定的端口)。现在你已经完成设置了!
用Appium测试你的app (Android)
首先,先确定你有一个而且必须是只能一个Android模拟器或者设备连接着。如果你输入adb devices,你应该只看到一个设备连接着。这将是Appium所用来测试的设备。当然,要连接一个设备,你需要准备好一个Android AVD (参考(,,或者)以了解更多)。 如果Android SDK工具在你的环境变量path下,你可以简单的执行:
emulator -avd &我的Avd名称&
然后等android模拟器启动。有时候,因为某些原因,adb会卡住。如果它没有显示任何的设备或其他故障,你可以使用下列指令来重启:
adb kill-server && adb devices
现在,确认Appium已经启动:
有几种方法来启动一个Appium程序(效果和通过adb启动一模一样):
只有apk或者zip,默认activity将会被启动。 (只设置了’app’环境参数)
apk + activity (‘app’ + ‘appActivity’ 环境参数)
apk + activity + intent (‘app’ + ‘appActivity’ + ‘appIntent’ 环境参数)
Activities 可以通过以下方式来指定:
名称 (如 appActivity: ‘com.helloworld.SayHello’)。
相对于 appPackage的路径 (如 appPackage: ‘com.helloworld’, appActivity=’.SayHello’)
如果“appWaitPackage’和’appWaitActivity”被指定,Appium
将自动等待,直到这些活动的被启动。你可以为实例指定多个等待的activity:
appActivity: ‘com.splash.SplashScreen’
appPackage: ‘com.splash’ appActivity: ’.SplashScreen’
appPackage: ‘com.splash’ appActivity: ’.SplashScreen,.LandingPage,com.why.GoThere’
如果你不是很清楚在apk中有哪些activity,你可以通过以下方式来查看:
Mac/Linux: ‘adb shell dumpsys window windows | grep mFocusedApp’
在 Ruby 控制台运行: ‘adb shell dumpsys window windows`.each_line.grep(/mFocusedApp/).first.strip’
在 Windows 终端运行 ‘adb shell dumpsys window windows’ 然后去看mFocusedApp这一行的内容。
然后执行你的WebDriver测试脚本,脚本必须包含下列的环境参数:
// javascript
platformName: 'Android',
platformVersion: '4.4',
deviceName: 'Android Emulator',
app: myApp
'platformName': 'Android',
'platformVersion': '4.4',
'deviceName': 'Android Emulator',
'app': myApp
public static $browsers = array(
'desiredCapabilities' =& array(
'platformName' =& 'Android',
'platformVersion' =& '4.4',
'deviceName' =& 'Android Emulator',
'app' =& $myApp
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator");
capabilities.setCapability(MobileCapabilityType.APP, myApp);
在这个脚本集里,myApp必须是下列其中之一:
一个.apk 或者.zip 档的本地绝对路径
一个包含着你的.apk档的zip压缩档的url
appium安装根目录下的一个示例app的路径
myAppPackage 必须是你的应用的java package,例如, com.example.android.myApp。
myAppActivity 必须是你的希望测试的Android activity, 例如, MainActivity。
在你选择的WebDriver库里,设定remote session使用上述的环境参数然后使用端口4723来连接本地服务器(或者是使用你在Appium启动时所设定的任意端口)。现在你已经设置完成了!
用Appium测试你的app (Android 设备 & 4.2, 以及混合app测试)
低于4.2版本的Android设备(API Level 17) 没有安装 Google 的.下面的范例是早期Appium在这些设备上的测试方法。对于早期的设备以及使用混合模式(webview-based)制作的apps, Appium 包含了另一种自动化测试工具。
要使用Selendroid, 只需要在之前提到的环境参数上稍作修改即可,添加 automationName 参数并指定Seledroid作为测试工具。通常你还需要在你的activity名称前加上. (如:在appActivity参数中使用.MainActivity 而不是 MainActivity) :
// javascript
automationName: 'Selendroid',
platformName: 'Android',
platformVersion: '2.3',
deviceName: 'Android Emulator',
app: myApp,
appPackage: 'com.mycompany.package',
appActivity: '.MainActivity'
'automationName': 'Selendroid',
'platformName': 'Android',
'platformVersion': '2.3',
'deviceName': 'Android Emulator',
'app': myApp,
'appPackage': 'com.mycompany.package',
'appActivity': '.MainActivity'
public static $browsers = array(
'desiredCapabilities' =& array(
'automationName' =& 'Selendroid',
'platformName' =& 'Android',
'platformVersion' =& '2.3',
'deviceName' =& 'Android Emulator',
'app' =& $myApp,
'appPackage' =& 'com.mycompany.package',
'appActivity'=& '.MainActivity'
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "Selendroid");
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "2.3");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator");
capabilities.setCapability(MobileCapabilityType.APP, myApp);
capabilities.setCapability(MobileCapabilityType.APP_PACKAGE: "com.mycompany.package");
capabilities.setCapability(MobileCapabilityType.APP_ACTIVITY: ".MainActivity");
这样Appium就会启动 Selendroid 测试会话取代默认的测试会话。使用Selendroid的缺点是有时候它的API跟Appium非常不同。所以我们建议你在为你的旧设备或者混合app写测试脚本之前先仔细的阅读。
Appium 服务器参数
node . [标志]
服务器标志
所有的标志都是可选的,但是有一些标志需要组合在一起才能生效。
进入 REPL 模式
--localizable-strings-dir
IOS only: 定位 .strings所在目录的相对路径
--localizable-strings-dir en.lproj
iOS: 基于模拟器编译的 app 的绝对路径或者设备目标的 bundle_id; Android: apk 文件的绝对路径--app /abs/path/to/my.app
(IOS-only)
.ipa 文件的绝对路径
--ipa /abs/path/to/my.ipa
-U, --udid
连接物理设备的唯一设备标识符
--udid 1adsf-sdfas-asdf-123sdf
-a, --address
监听的 ip 地址
--address 0.0.0.0
-p, --port
监听的端口
--port 4723
-ca, --callback-address
回调IP地址 (默认: 相同的IP地址)
--callback-address 127.0.0.1
-cp, --callback-port
回调端口号 (默认: 相同的端口号)
--callback-port 4723
-bp, --bootstrap-port
(Android-only) 连接设备的端口号
--bootstrap-port 4724
-k, --keep-artifacts
弃用,无效。trace信息现在保留tmp目录下,每次运行前会清除该目录中的信息。 也可以参考 –trace-dir 。
-r, --backend-retries
(iOS-only) 遇到 crash 或者 超时,Instrument 重新启动的次数。
--backend-retries 3
--session-override
允许 session 被覆盖 (冲突的话)
--full-reset
(iOS) 删除整个模拟器目录。 (Android) 通过卸载应用(而不是清除数据)重置应用状态。在 Android 上,session 完成后也会删除应用。
--no-reset
session 之间不重置应用状态 (iOS: 不删除应用的 plist 文件; Android: 在创建一个新的 session 前不删除应用。)
-l, --pre-launch
在第一个 session 前,预启动应用 (iOS 需要 –app 参数,Android 需要 –app-pkg 和 –app-activity)
-lt, --launch-timeout
(iOS-only) 等待 Instruments 启动的时间
将日志输出到指定文件
--log /path/to/appium.log
--log-level
日志级别; 默认 (console[:file]): debug[:debug]
--log-level debug
--log-timestamp
在终端输出里显示时间戳
--local-timezone
使用本地时间戳
--log-no-colors
不在终端输出中显示颜色
-G, --webhook
同时发送日志到 HTTP 监听器
--webhook localhost:9876
--native-instruments-lib
(IOS-only) iOS 内建了一个怪异的不可能避免的延迟。我们在 Appium 里修复了它。如果你想用原来的,你可以使用这个参数。
(Android-only) 你要运行的apk的java包。 (例如, com.example.android.myApp)
--app-pkg com.example.android.myApp
--app-activity
(Android-only) 打开应用时,启动的 Activity 的名字(比如, MainActivity)
--app-activity MainActivity
--app-wait-package
(Android-only) 你想等待的 Activity 的包名。(比如, com.example.android.myApp)
--app-wait-package com.example.android.myApp
--app-wait-activity
(Android-only) 你想等待的 Activity 名字(比如, SplashActivity)
--app-wait-activity SplashActivity
--android-coverage
(Android-only) 完全符合条件的 instrumentation 类。 作为命令 adb shell am instrument -e coverage true -w 的 -w 的参数
--android-coverage com.my.Pkg/com.my.Pkg.instrumentation.MyInstrumentation
(Android-only) 要启动的 avd 的名字
--avd-args
(Android-only) 添加额外的参数给要启动avd
--avd-args -no-snapshot-load
--device-ready-timeout
(Android-only) 等待设备准备好的时间,以秒为单位
--device-ready-timeout 5
(IOS-Onl

我要回帖

更多关于 ipad屏幕失灵滑动不了 的文章

 

随机推荐