appium介绍(9)

Appium是一个移动端的自动化框架,可用于测试原生应用,移动网页应用和混合型应用,且是跨平台的。可用于IOSAndroid以及firefox的操作系统。原生的应用是指用androidiossdk编写的应用,移动网页应用是指网页应用,类似于iossafari应用或者Chrome应用或者类浏览器的应用。混合应用是指一种包裹webview的应用,原生应用于网页内容交互性的应用。

重要的是Appium是跨平台的,何为跨平台,意思就是可以针对不同的平台用一套api来编写测试用例。

 

Appium 中文 Appium API文档  

https://testerhome.com/topics/3144

 

案例源码下载地址

https://github.com/appium/sample-code

 

优点

• 跨架构,native hybrid webview

• 跨设备,android ios firefoxos

• 跨语言, java python ruby nodejs php

• 跨app, 可以在多个app之间交互

• 不依赖源代码

• 不限制测试框架和平台

 

原理

以后是基于 uiautomator框架实现查找注入事件的, 框架实现查找注入事件的,框架实现查找注入事件的, 4.2 以前则是 instrumentation i框架的,并封装成一个叫 框架的, Selendroid 这玩意提供服务
Client ent是我们编写的 webdriver 脚本。中间是 appium启动 server  (默认监听  4723 端口 ),
appium server  会把请求转发给中间件 会把请求转发给中间件 Bootstrap.jar  ,它是用java写的,安装在 手机上 .Bootstrap监听 4723端口并接收appium  的命令,最终通过调 的命令过调 用 UiAutomator U 的命令来实现。
Bootstrap将执行的结果返回给 将执行的结果返回给 appium server 。
Appiumserver再将结果返回给 client端

 

 

 

Appium 概念

C/S 架构

Appium 的核心是一个 web 服务器,它提供了一套 REST 的接口。它收到客户端的连接,监听到命令,接着在移动设备上执行这些命令,然后将执行结果放在 HTTP响应中返还给客户端。事实上,这种客户端/服务端的架构给予了许多的可能性:比如我们可以使用任何实现了该客户端的语言来写我们的测试代码。比如我们可以把服务端放在不同
的机器上。比如我们可以只写测试代码,然后使用像 Sauce Labs 这样的云服务来解释命令。

Session

自动化始终围绕一个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 文档,查看完整的 capabilities 列表。

Appium Server

Appium server 是用 Node.js 写的。我们可以用源码编译或者从 NPM 直接安装。

Appium 服务端

Appium 服务端有很多语言库 Java, Ruby, Python, PHP, JavaScript 和 C#,这些库都实现了
Appium 对 WebDriver 协议的扩展。当使用 Appium 的时候,你只需使用这些库代替常规的 WebDriver 库就可以了。
你可以从这里看到所有的库的列表。

 

 

UiSelector

  概述:

    按照一定的条件(例如控件的text值,资源id),定位界面上的元素。UiSelector对象的最终目的是去构造一个UiObject对象。

  摘要:

1、根据text构造:

函数返回值

函数体

说明

用法

UiSelector

text(String text)

根据控件text属性的内容构造出UiSelector对象

例如,一个控件text的值是发现UiSelector s = new UiSelector().text("发现");

UiSelector

textContains(String text)

根据控件text属性包含的内容构造出UiSelector对象

同上例子:UiSelector s = new UiSelector().textContains("");

UiSelector

textMatches(String regex) 

根据控件text属性正则表达式的内容构造出UiSelector对象

正则表达式语法参考网上资料即可。

UiSelector

textStartsWith(String text)

根据控件text属性开始的内容构造出UiSelector对象

同上例子:UiSelector s = new UiSelector().textStartsWith("");

      比较常用,准确度也比较高,中文查找的时候,如果遇到 “UiOjbectNotFoundException”的时候,记得把项目的编码格式改为utf-8

 

2、根据description构造:

UiSelector

description(String desc)

根据控件content-desc属性的内容构造出UiSelector对象

UiSelector

descriptionContains(String desc)

包含**

UiSelector

descriptionMatches(String regex)

正则

UiSelector

descriptionStartsWith(String desc)

**开始

 

      同text的用法基本一致,也是比较靠谱的一种方式。

 

3、根据资源id

UiSelector

resourceId(String id)

根据资源id获取对象,例如:UiSelector s = new UiSelector().resourceId("com.tencent.mm:id/b8m")

UiSelector

resourceIdMatches(String regex)

根据资源id的正则表达式获取对象

 

4、根据类:

UiSelector className(String  className)

        根据控件的类名来找到UiSelector对象。

        但是呢?因为一般Android布局的时候,同样的控件类名都是一样的。

        因此我在微信的登录界面调用: UiSelector s = new UiSelector().className("android.widget.TextView")这句话,它得到的就是我左上开始算第一个class名称为“android.widget.TextView”的控件。

 

UiSelector instance (int instance)

        上面提到的假如我们想获取屏幕上电话号码的那个TextView使用这样方法,就可以使用instance

 UiSelector s = new UiSelector().className("android.widget.TextView").instance(1);

UiSelector index(int index)

        用法和上面的instance差不多,谷歌的原文说这个方法是unreliable的,推荐使用instance方法。

UiSelector childSelector(UiSelector selector)

        有的时候假如子控件不好获得,而其父控件比较好获得的时候,我们通常采用这样的方式,例如下面:

           我们目前选中的是LinearLayout,这个Android中的一种布局,它的里面嵌套了两个控件,一个是ImageView,另一个是EditText。这们这里就通过LinearLayout这个控件找到它的子控件。

        很明显,父控件id已经给定。我们先得到父控件:UiSelector s_p = new UiSelector().resourceId("com.tencent.mm:id/axj");

        其次 UiSelector s_c= s_p.childSelector( new UiSelector().className("android.widget.EditText") );

        在它的父控件的childSelector方法中传入一个带有一定特征的UiSelector对象,即可得到子控件,这里 s_c就是输入框的UiSelector对象。

UiSelector fromParent(UiSelector selector)

        有的时候父控件也不好获得,而是同级的控件(同属一个parent)比较好获取,那么使用这样方法,还拿上面的举例:

        我们先得到EditTextUiSelector对象:UiSelector s1 = new UiSelector().resourceId("com.tencent.mm:id/axc");

        得到和它同样一个父控件的ImageViewUiSelector对象:UiSelector s2 = fromParent( new UiSelector().className("android.widget.ImageView") );

5、根据特有属性:

UiSelector

checked(boolean val)

根据是否可check来构造出UiSelector对象

UiSelector

chickable(boolean val)

 

UiSelector

enabled(boolean val)

 

UiSelector

focusable(boolean val)

 

UiSelector

longClickable(boolean val)

 

UiSelector

scrollable(boolean val)

 

UiSelector

selected(boolean val)

 

      举个简单的例如,假如当前的界面,只有一个checkbox是勾选状态,你就可以这样得到:UiSelector s2 = new UiSelector().checked(true)