一、什么是Appium
Appium是一个开源、跨平台的测试框架,可以用来测试原生及混合的移动端应用。Appium支持IOS、Android及FirefoxOS平台。Appium使用WebDriver的json wire协议,来驱动Apple系统的UIAutomation库、Android系统的UIAutomator框架。Appium对IOS系统的支持得益于Dan Cuellar’s对于IOS自动化的研究。Appium也集成了Selendroid,来支持老android版本。
Appium支持Selenium WebDriver支持的所有语言,如java、Object-C、JavaScript、Php、Python、Ruby、C#、Clojure,或者Perl语言,更可以使用Selenium WebDriver的Api。Appium支持任何一种测试框架。如果只使用Apple的UIAutomation,我们只能用javascript来编写测试用例,而且只能用Instruction来运行测试用例。同样,如果只使用Google的UIAutomation,我们就只能用java来编写测试用例。Appium实现了真正的跨平台自动化测试。
appium选择了client-server的设计模式。只要client能够发送http请求给server,那么的话client用什么语言来实现都是可以的,这就是appium及webdriver如何做到支持多语言的;
下面这段介绍来自于appium的官网。
Appium is an open-source tool you can use to automate mobile native, mobile web, and mobile hybrid applications on iOS and Android platforms. “Mobile native apps” are those written using the iOS or Android SDKs. “Mobile web apps” are web apps accessed using a mobile browser (Appium supports Safari on iOS and Chrome on Android). “Mobile hybrid apps” have a native wrapper around a “webview” – a native control that enables interaction with web content. Projects like Phonegap, for example, make it easy to build apps using web technologies that are then bundled into a native wrapper – these are hybrid apps. Importantly, Appium is “cross-platform”: it allows you to write tests against multiple platforms (iOS, Android), using the same API. This enables a large or total amount of code reuse between iOS and Android testsuites.
二、Appium的工作原理及其相关基本概念
2.1 工作原理
2.1.1 Android
在Android端,appium基于WebDriver协议,利用Bootstrap.jar,最后通过调⽤用UiAutomator的命令,实现App的自动化测试。
UiAutomator测试框架是Android SDK自带的App UI自动化测试Java库。
另外由于UiAutomator对H5的支持有限,appium引入了chromedriver以及safaridriver等来实现基于H5的自动化。
appium 在android端工作流
-
client端也就是我们 test script是我们的webdriver测试脚本。
-
中间是起的Appium的服务,Appium在服务端起了一个Server(4723端口),跟selenium Webdriver测试框架类似, Appium⽀持标准的WebDriver JSONWireProtocol。在这里提供它提供了一套REST的接口,Appium Server接收web driver client标准rest请求,解析请求内容,调⽤用对应的框架响应操作。
-
appium server会把请求转发给中间件Bootstrap.jar ,它是用java写的,安装在手机上.Bootstrap监听4724端口并接收appium 的命令,最终通过调⽤用UiAutomator的命令来实现。
-
最后Bootstrap将执行的结果返回给appium server。
-
appium server再将结果返回给 appium client。
2.1.2 ios
在IOS端,appium同样使⽤WebDriver的一套协议。
与Android端测试框架不同的是,appium ios封装了apple的 Instruments框架,主要用了Instrument里的UI Automation(Apple的⾃自动化测试框架),然后在设备中注⼊入bootstrap.js进⾏行监听。
appium 在ios端工作流
-
client端 依然是 test script是我们的webdriver测试脚本。
-
中间是起的Appium的服务,Appium在服务端起了一个Server(4723端口),跟selenium Webdriver测试框架类似, Appium⽀持标准的WebDriver JSONWireProtocol。在这里提供它提供了一套REST的接口,Appium Server接收web driver client标准rest请求,解析请求内容,调⽤用对应的框架响应操作。
-
appium server调用instruments.js 启动⼀一个socket server,同时分出一个⼦子进程运⾏instruments.app,将bootstrap.js(一个UIAutomation脚本)注⼊入到device⽤于和外界进行交互
-
最后Bootstrap.js将执行的结果返回给appium server
-
appium server再将结果返回给 appium client。
所以我们可以看到android与ios区别在于appium 将请求转发到bootstrap.js或者bootstrap.jar.然后由bootstrap 驱动UIAutomation和UiAutomator去devices上完成具体的动作。
2.2 Client/Server Architecture
appium的核心其实是一个暴露了一系列REST API的server。
这个server的功能其实很简单:监听一个端口,然后接收由client发送来的command。翻译这些command,把这些command转成移动设备可以理解的形式发送给移动设备,然后移动设备执行完这些command后把执行结果返回给appium server,appium server再把执行结果返回给client。
在这里client其实就是发起command的设备,一般来说就是我们代码执行的机器,执行appium测试代码的机器。狭义点理解,可以把client理解成是代码,这些代码可以是java/ruby/python/js的,只要它实现了webdriver标准协议就可以。
这样的设计思想带来了一些好处:
-
可以带来多语言的支持;
-
可以把server放在任意机器上,哪怕是云服务器都可以;(是的,appium和webdriver天生适合云测试)
2.3 Session
session就是一个会话,在webdriver/appium,你的所有工作永远都是在session start后才可以进行的。一般来说,通过POST /session这个URL,然后传入Desired Capabilities就可以开启session了。
开启session后,会返回一个全局唯一的session id,以后几乎所有的请求都必须带上这个session id,因为这个seesion id代表了你所打开的浏览器或者是移动设备的模拟器。
进一步思考一下,由于session id是全局唯一,那么在同一台机器上启动多个session就变成了可能,这也就是selenium gird所依赖的具体理论根据。
2.4 Desired Capabilities
Desired Capabilities携带了一些配置信息。从本质上讲,这个东东是key-value形式的对象。你可以理解成是java里的map,python里的字典,ruby里的hash以及js里的json对象。实际上Desired Capabilities在传输时就是json对象。
Desired Capabilities最重要的作用是告诉server本次测试的上下文。这次是要进行浏览器测试还是移动端测试?如果是移动端测试的话是测试android还是ios,如果测试android的话那么我们要测试哪个app? server的这些疑问Desired Capabilities都必须给予解答,否则server不买账,自然就无法完成移动app或者是浏览器的启动。
具体例子如下:
For example, we might set the platformName capability to iOS to tell Appium that we want an iOS session, rather than an Android one. Or we might set the safariAllowPopupscapability to true in order to ensure that, during a Safari automation session, we’re allowed to use JavaScript to open up new windows. See the capabilities doc for the complete list of capabilities available for Appium
2.5 Appium Server
这就是每次我们在命令行用appium命令打开的东西。
Appium server 是用 Node.js 写的。我们可以用源码编译或者从 NPM 直接安装。
2.6 Appium 服务端
Appium 服务端有很多语言库 Java, Ruby, Python, PHP, JavaScript 和 C#,这些库都实现了 Appium 对 WebDriver 协议的扩展。当使用 Appium 的时候,你只需使用这些库代替常规的 WebDriver 库就可以了。 你可以从这里看到所有的库的列表。
2.7 Appium Clients
由于原生的webdriver api是为web端设计的,因此在移动端用起来会有点不伦不类。appium官方提供了一套appium client,涵盖多种语言ruby/java/python,在我看来ruby client是实现最好的。在测试的时候,一般要使用这些client库去替换原生的webdriver库。这实际上不是替换,算是client对原生webdriver进行了一些移动端的扩展,加入了一些方便的方法,比如swipe之类,appium client让我们可以更方便的写出可读性更好的测试用例。
2.8 Appium.app, Appium.exe
官方提供了GUI封装的Appium服务端下载,它封装了Appium服务端的所有依赖,用户不用担心怎样安装Node.js。GUI封装的Appium中还包括了一个Inspector工具,可以帮助用户检查应用的节目层级,虽然Android官方的SDK中的Android Device Monitor和UI Automator Viewer也可以实现,但是相比较Inspector还是有不足之处。
三、Appium并发
关于appium并发,我将之分为2类,第一类单机并发。第二类基于selenium grid 多节点并发测试,也可称之为云测。
3.1 appium 单机并发
Android并发测试
Appium提供了在一台设备上启动多个Android会话的方案。
appium -p 4492 -bp 2251 -U 32456
启动多个Android会话的重要指令包括:
指令 | 功能 |
---|---|
-p | Appium的主要端口 |
-U | 设备id |
-bp | Appium bootstrap端口 |
–chromedriver-port | chromedriver端口(当使用了webviews或者chrome) |
–selendroid-port | selendroid端口(当使用了selendroid) |
iOS并发测试
不幸的是,IOS不能进行本地并发测试。跟Android不一样,IOS在同一时间只能启动一个版本的模拟器来运行多个测试。
总结: 单机并发目前只能在android实现,且必须启动n个appium server 对应不同devices,这里devices可以是真机或模拟器。但是必须保证端口后没有重复使用。 接下来工作就是利用测试框架(testng,jasmine,rspec,cucumber等)将测试分发到不同appium server上。
代码示例:GitHub
代码解析:
-
首先让我们来看下代码中的AppiumParallelTest这个类,他们先判断操作系统,并获取操作系统上连接的devices。利用AndroidDeviceConfiguration.java 与IOSDeviceConfiguration.java 中的getIOSUDID,getDevices方法分别获取真机与模拟器的id.
-
然后利用startAppiumServer方法启动appium server, 利用appiumServerForAndroid()或者appiumServerForIOS().
3.2 appium grid 分布式并发
1、start selenium grid sever
java -jar selenium-server-standalone-2.47.1.jar -port 4444 -role hub -hub http://192.168.199.140:4444/grid/registe
2、Registered appium server as the grid node
appium --nodeconfig appium_node_S3.json -p 4823 -bp 3356 -U "192.168.99.104:5555" --chromedriver-port 4738
3、Configure the test script,run the tests
@BeforeTest
@Parameters({"deviceName"})
public void setUp(String deviceName) throws Exception {
capabilities.setCapability("deviceName",deviceName);
capabilities.setCapability("platformVersion", "5.0");
capabilities.setCapability("app", getApp("ContactManager.apk"));
setUpAndroidDriver();
}
GRID NODE CONFIGURATION EXAMPLE JSON FILE
{
"capabilities":
[
{ "deviceName": "192.168.56.101:5555",
"browserName": "<e.g._iPhone5_or_iPad4>",
"version":"<version_of_iOS_e.g._7.1>",
"maxInstances": 1,
"platform":"<platform_e.g._MAC_or_ANDROID>"
}
],
"configuration":
{
"cleanUpCycle":2000,
"timeout":30000,
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
"url":"http://<host_name_appium_server_or_ip-address_appium_server>:<appium_port>/wd/hub",
"host": <host_name_appium_server_or_ip-address_appium_server>,
"port": <appium_port>,
"maxSession": 1,
"register": true,
"registerCycle": 5000,
"hubPort": <grid_port>,
"hubHost": "<Grid_host_name_or_grid_ip-address>"
}
}
四、支持平台及其需求
支持平台
-
iOS
-
Android
-
FirefoxOS
依赖
为了运行测试,针对不同的移动平台,你需要配置下环境,下面列出相关的依赖平台的需求。
如果你想通过 npm install 安装的 appium 来运行 Appium 或者研究 Appium 或者为 Appium 贡献力量。你需要安装 [node.js 和 npm] (https://nodejs.org/en/) 0.10 或者更高版本 (使用 n 或者 brew install node 来安装 Nodejs,确保安装过程中,你没有使用任何 sudo,否则你会遇到很多问题)。我们推荐最新的稳定版本。
你可以使用 appium-doctor 来验证 Appium 的所有依赖。运行 appium-doctor,然后提供 --ios 或者 --android 参数来验证两个平台的依赖是否配置正确。如果从源代码运行,你可以使用 bin/appium-doctor.js 或者 node bin/appium-doctor.js
iOS 需求
- Mac OS X 10.7 或者更高,推荐 10.9.2
- XCode >= 4.6.3,推荐 5.1.1
- Apple Developer Tools (iPhone simulator SDK, command line tools)
- 确保你已经读了我们写的如何配置 iOS 测试环境的文档
Android 需求
- Android SDK API >= 17 (额外的特性需要 18/19)
-
Appium 支持OS X,Linux,Windows 上的 Android,确保你是按照如下文档的指示来配置不同的测试环境的。
FirefoxOS 需求
限制
如果你在windows上安装appium,你没法使用预编译专用于OS X的.app文件,你也将不能测试IOS apps,因为appium依赖OS X专用的库来支持IOS测试。这意味着你只能通过在mac上来运行IOS的app测试。这点限制挺大。