您的位置:首页 > 移动开发 > Android开发

浅析Android自动化测试基础技术(一)

2016-03-08 19:19 609 查看

模拟用户点击或按键操作

要做到Android终端的自动化测试,不可避免的需要通过程序来模拟UI界面点击,如果是要开发一款自动化测试的app软件,则调用MotionEvent的底层点击方法是非常有效和稳定的。

首先将MotionEvent的源码看下,大部分可以获取所有的触控事件内容,这儿我们关心如何模拟点击,所以看到obtain这个方法:



前两个参数分别为事件的开始和完成时间,使用的是uptimeMillis开机时间来构造。

第三个参数为事件的类型,因为一般我们点击一次屏幕是要经历多个过程,从action_down,action_up等(需要详细的说明内容可以查看这篇文章http://blog.csdn.net/bigconvience/article/details/26611003)。

第四、五个参数为坐标点,第六个默认为0(这儿暂时没弄清楚:( );

其他参数是适用于较为复杂的操作,这儿暂时不详细描述了;

为了模拟一个最简单的点击事件,我们需要down和up(0和1),所以我封装了个简单的点击方法如下:

/**
* 点击屏幕的坐标点
*
* @param x
* @param y
*/
public void clickOnScreen(float x, float y) {
long downTime = SystemClock.uptimeMillis();
long eventTime = SystemClock.uptimeMillis();
MotionEvent event = MotionEvent.obtain(downTime, eventTime, 0, x, y, 0);
MotionEvent event2 = MotionEvent.obtain(downTime, eventTime, 1, x, y, 0);
try {
sendPointerSync(event);
sendPointerSync(event2);
sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
再通过IuputManager将事件注入到屏幕上(因为安全问题,所以注入需要系统权限或Root权限android.uid.system)

/**
* 发送点击事件 2013-9-17 hwy
*
* @param event
*/
private void sendPointerSync(MotionEvent event) {
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
}
InputManager.getInstance().injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}


同理,将其扩展为长按点击,只需要在发送down和up事件之间加入延时

/**
* 长按屏幕
*
* @param x
* @param y
* @param clickTime
*            长按时间
*/
public void clicklongOnScreen(float x, float y, int clickTime) {
long downTime = SystemClock.uptimeMillis();
long eventTime = SystemClock.uptimeMillis();
try {
MotionEvent event = MotionEvent.obtain(downTime, eventTime, 0, x, y, 0);
sendPointerSync(event);
sleep(clickTime);
eventTime = SystemClock.uptimeMillis();
MotionEvent event2 = MotionEvent.obtain(downTime, eventTime, 1, x, y, 0);
sendPointerSync(event2);
sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}


如果要实现拖拽,也是如上炮制,只需要在down和up之间再加入1次移动move的事件即可,这儿就不列出具体代码了。

如何发送按键操作?通过keyevent对象来实现,例如点击home键:

// Home
mOperate.sendKeyDownUpSync(KeyEvent.KEYCODE_HOME);
mOperate.sleep(2000);


/**
* 发送按键事件
*
* @param KeyEvent
*            .KEYCODE_BACK 返回 KeyEvent.KEYCODE_HOME home键
*
*/
public void sendKeyDownUpSync(int key) {
sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, key));
sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, key));
}
/* 私有函数 */
/**
* @param event
*/
@SuppressLint("NewApi")
private void sendKeySync(KeyEvent event) {
long downTime = event.getDownTime();
long eventTime = event.getEventTime();
int action = event.getAction();
int code = event.getKeyCode();
int repeatCount = event.getRepeatCount();
int metaState = event.getMetaState();
int deviceId = event.getDeviceId();
int scancode = event.getScanCode();
int source = event.getSource();
int flags = event.getFlags();
if (source == InputDevice.SOURCE_UNKNOWN) {
source = InputDevice.SOURCE_KEYBOARD;
}
if (eventTime == 0) {
eventTime = SystemClock.uptimeMillis();
}
if (downTime == 0) {
downTime = eventTime;
}
KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState, deviceId, scancode,
flags | KeyEvent.FLAG_FROM_SYSTEM, source);
InputManager.getInstance().injectInputEvent(newEvent, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: