手机自动化测试:appium源码分析之bootstrap三
手机自动化测试:appium源码分析之bootstrap三
研究bootstrap源码,我们可以通过代码的结构,可以看出来appium的扩展思路和实现方式,从中可以添加我们自己要的功能,针对appium进行定制,poptest在2015年10月24日开设appium的课程,课程采用真实的商业项目进行培训,用现在互联网金融的业务。
bootstrap代码中io.appium.android.bootstrap.handler包中的类都是对应的指令类,核心都是execute方法。
下面我们看下HashMap:
private static HashMap<String, CommandHandler> map = new HashMap<String, CommandHandler>();
static {
map.put("waitForIdle", new WaitForIdle());
map.put("clear", new Clear());
map.put("orientation", new Orientation());
map.put("swipe", new Swipe());
map.put("flick", new Flick());
map.put("drag", new Drag());
map.put("pinch", new Pinch());
map.put("click", new Click());
map.put("touchLongClick", new TouchLongClick());
map.put("touchDown", new TouchDown());
map.put("touchUp", new TouchUp());
map.put("touchMove", new TouchMove());
map.put("getText", new GetText());
map.put("setText", new SetText());
map.put("getName", new GetName());
map.put("getAttribute", new GetAttribute());
map.put("getDeviceSize", new GetDeviceSize());
map.put("scrollTo", new ScrollTo());
map.put("find", new Find());
map.put("getLocation", new GetLocation());
map.put("getSize", new GetSize());
map.put("wake", new Wake());
map.put("pressBack", new PressBack());
map.put("dumpWindowHierarchy", new DumpWindowHierarchy());
map.put("pressKeyCode", new PressKeyCode());
map.put("longPressKeyCode", new LongPressKeyCode());
map.put("takeScreenshot", new TakeScreenshot());
map.put("updateStrings", new UpdateStrings());
map.put("getDataDir", new GetDataDir());
map.put("performMultiPointerGesture", new MultiPointerGesture());
map.put("openNotification", new OpenNotification());
}
appium底层调用的是uiautomator的api。我们看下click动作:
package io.appium.android.bootstrap.handler;
import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.core.UiObjectNotFoundException;
import io.appium.android.bootstrap.*;
import org.json.JSONException;
import java.util.ArrayList;
import java.util.Hashtable;
/**
* This handler is used to click elements in the Android UI.
*
* Based on the element Id, click that element.
*
*/
public class Click extends CommandHandler {
/*
* @param command The {@link AndroidCommand}
*
* @return {@link AndroidCommandResult}
*
* @throws JSONException
*
* @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.
* bootstrap.AndroidCommand)
*/
@Override
public AndroidCommandResult execute(final AndroidCommand command)
throws JSONException {
if (command.isElementCommand()) {
try {
final AndroidElement el = command.getElement();
el.click();
return getSuccessResult(true);
} catch (final UiObjectNotFoundException e) {
return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT,
e.getMessage());
} catch (final Exception e) { // handle NullPointerException
return getErrorResult("Unknown error");
}
} else {
final Hashtable<String, Object> params = command.params();
final Double[] coords = { Double.parseDouble(params.get("x").toString()),
Double.parseDouble(params.get("y").toString()) };
final ArrayList<Integer> posVals = absPosFromCoords(coords);
final boolean res = UiDevice.getInstance().click(posVals.get(0),
posVals.get(1));
return getSuccessResult(res);
}
}
}
该类中的方法处理点击事件,首先方法会判断你传入的命令参数是针对控件对象的还是坐标的
如果参数是控件,会获得命令中的控件对象,然后调用click方法
AndroidElement.java
public boolean click() throws UiObjectNotFoundException {
return el.click();
}
在代码中el如下定义:private final UiObject el;
说明调用的是uiautomator中的UiObject类的click方法,click方法的作用就是点击该控件中心,点击完成后调用getSuccessResult
/**
* Returns success along with the payload.
*
* @param value
* @return {@link AndroidCommandResult}
*/
protected AndroidCommandResult getSuccessResult(final Object value) {
return new AndroidCommandResult(WDStatus.SUCCESS, value);
}
创建AndroidCommandResult新对象,传入WDStatus.SUCCESS,和value(我们这里传入的值为true).首先看一下SUCCESS的值,该值存放在枚举类WDStatus中。
SUCCESS (0, "The command executed successfully."),
下面进入AndroidCommandResult类的构造方法里。
JSONObject json;
public AndroidCommandResult(final WDStatus status, final Object val) {
json = new JSONObject();
try {
json.put("status", status.code());
json.put("value", val);
} catch (final JSONException e) {
Logger.error("Couldn't create android command result!");
}
}
构造方法里把传入的参数保存在了json对象中,以键值对的形式。好了,条件为控件的情况分析结束,下面开始分析坐标。
坐标
如果是坐标的话,程序会获得命令里的坐标参数,保存在Double数组中。
final Hashtable<String, Object> params = command.params();
final Double[] coords = { Double.parseDouble(params.get("x").toString()),
Double.parseDouble(params.get("y").toString()) };
接下来会通过absPosFromCoords方法将Double转换为List。所以下面来看absPosFromCoords方法的实现:
/**
* Given a position, it will return either the position based on percentage
* (by passing in a double between 0 and 1) or absolute position based on the
* coordinates entered.
*
* @param coordVals
* @return ArrayList<Integer>
*/
protected static ArrayList<Integer> absPosFromCoords(final Double[] coordVals) {
final ArrayList<Integer> retPos = new ArrayList<Integer>();
final UiDevice d = UiDevice.getInstance();
final Double screenX = (double) d.getDisplayWidth();
final Double screenY = (double) d.getDisplayHeight();
if (coordVals[0] < 1 && coordVals[1] < 1) {
retPos.add((int) (screenX * coordVals[0]));
retPos.add((int) (screenY * coordVals[1]));
} else {
retPos.add(coordVals[0].intValue());
retPos.add(coordVals[1].intValue());
}
return retPos;
}
首先会判断传入的坐标是以百分比的形式还是以坐标的形式。如果是百分比说明你传入的不是绝对坐标,而是相对坐标,这种情况你就需要获取屏幕的尺寸,然后和百分比做计算得到当前屏幕中你所要点击的坐标点。如果传入的是坐标,那就直接将Double类型的值转化为Int的值。
经过上面的一番操作以后,会得到确切坐标值保存在数组中返回。
然后程序调用UiDevice的click方法点击啦:
final boolean res = UiDevice.getInstance().click(posVals.get(0), posVals.get(1));
最后返回一个成功的AndroidCommandResult对象。
手机自动化测试:appium源码分析之bootstrap三的更多相关文章
- 手机自动化测试:appium源码分析之bootstrap二
手机自动化测试:appium源码分析之bootstrap二 在bootstrap项目中的io.appium.android.bootstrap.handler包中的类都是对应的指令类, priva ...
- 手机自动化测试:appium源码分析之bootstrap一
手机自动化测试:appium源码分析之bootstrap一 前言: poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.popte ...
- 手机自动化测试:appium源码分析之bootstrap十七
手机自动化测试:appium源码分析之bootstrap十七 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...
- 手机自动化测试:appium源码分析之bootstrap十六
手机自动化测试:appium源码分析之bootstrap十六 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...
- 手机自动化测试:appium源码分析之bootstrap十五
手机自动化测试:appium源码分析之bootstrap十五 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...
- 手机自动化测试:appium源码分析之bootstrap十四
手机自动化测试:appium源码分析之bootstrap十四 poptest(www.poptest.cn)是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开 ...
- 手机自动化测试:appium源码分析之bootstrap十三
手机自动化测试:appium源码分析之bootstrap十三 poptest(www.poptest.cn)是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开 ...
- 手机自动化测试:appium源码分析之bootstrap十一
手机自动化测试:appium源码分析之bootstrap十一 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...
- 手机自动化测试:appium源码分析之bootstrap十二
手机自动化测试:appium源码分析之bootstrap十二 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...
随机推荐
- C++inserter
C++的迭代器适配器中常用的有插入迭代器(Inser Iterator).流迭代器(Stream Iterator)和逆向迭代器(Reverse Iterator)等! 本文主要是介绍插入迭代器(In ...
- Ant学习总结5(配合Ant视频8,9)
重点: Ant的属性介绍: <property name="build.dir" value="build"/>注意:一般对于常量都会定义成为属性 ...
- [NOI2007]货币兑换Cash(DP+动态凸包)
第一次打动态凸包维护dp,感觉学到了超级多的东西. 首先,set是如此的好用!!!可以通过控制一个flag来实现两种查询,维护凸包和查找斜率k 不过就是重载运算符和一些细节方面有些恶心,90行解决 后 ...
- BZOJ 1095: [ZJOI2007]Hide 捉迷藏(线段树维护括号序列)
这个嘛= =链剖貌似可行,不过好像代码长度很长,懒得打(其实是自己太弱了QAQ)百度了一下才知道有一种高大上的叫括号序列的东西= = 岛娘真是太厉害了,先丢链接:http://www.shuizilo ...
- android学习4——View的长宽问题
画形状的时间经常会用到点的坐标,这时原点O的位置就非常重要.在像素为1280*720的设备上画一条直线.代码如下所示: import android.app.Activity; import andr ...
- .Net开源oss项目进度更新(含小程序接口)
和大家分享下当前OSS开源项目的进度情况: 一. OSS.Common [开源中国] [github] 经过昨天的努力,oss.common项目初步完成了对.net standard的支持,迁移过程本 ...
- HTML入门
一些说明 写在前面:HTML和CSS,当你了解所有规则后,你应该多写页面并记录你出现的问题,这才是学习HTML和CSS的最佳方法 这是我学习一段时间之后,再次回顾HTML,希望大家也对HTML有不一样 ...
- HBase、HDFS和MapReduce架构异同简解
HBase.HDFS和MapReduce架构异同 .. HBase(公司架构模型) HDFS2.0(公司架构模型) MR2.0(公司架构模型) MR1.0(公司架构模型) 中央 HMaster Nam ...
- 用GDB调试程序
转自:http://blog.csdn.net/haoel/article/details/2879 是一篇从基础讲gdb的博文 用GDB调试程序 GDB概述---- GDB是GNU开源组织发布的一个 ...
- 关于mvc中传入DataTable到视图的应用
MVC 中 如果是多表连接查询出的数据需要重新定义一个ViewModel,觉得很是麻烦,所以可以通过传一个DataTable到视图中可以避免这个问题 但是不知道会有什么不好的地方,有这方面经验的大神有 ...