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

来源:互联网 发布:c语言比较三个数大小 编辑:程序博客网 时间:2024/06/07 22:27

在上面一篇文章中介绍了Android模拟点击按键的技术,但是对于自动化测试来说,使用坐标来编写执行脚本是很难维护的,所以需要一种更灵活的方式。

获取控件信息

通过Android sdk提供的工具,hierachyviewer处理工具能获取到已连接Android设备的当前界面的控件树信息,并且对每个控件的基础信息进行了导出,其中有一部分的控件信息是控件的rect,通过这个rect我们可以获取到控件的中心坐标。
但是这个方法获取的速度太慢了,所以在Android4.4后出现了uiautomatorviewer能生成较为简单的控件树信息,通过查看uiautomator的源码:



可以看到使用了Accessbility这个Class,通过api查看这也是Android手机上辅助服务的核心方法,主要是用来帮助盲人读取界面文字语音播放的。正好可以通过这个方法来实现我们的自动化测试用来识别控件。
所以需要自定义一个辅助服务,并且开启服务,首先在manifest注册服务


获取nodes时同时判断是否连接服务,如果没有连接上则开启连接,其中重连10次如果一直不能连接上则放弃该操作:
/** * update the infos list */@SuppressLint("NewApi")public void getNodes() {AccessibilityNodeInfo rootNode = null;rootNode = getRootNode();if (rootNode == null) {System.err.println("ERROR: null root node returned by AccessibilityNodeInfosObtain.");}AccessibilityNodeInfoDumper dumper = new AccessibilityNodeInfoDumper(mContext);infos = dumper.dumpWindow(rootNode);}
/** * Get root node. *  * @return AccessibilityNodeInfo */private AccessibilityNodeInfo getRootNode() {AccessibilityNodeInfo rootNode = null;int i = 0;while (i < 10) {AccessibilityEventService eventService = AccessibilityEventService.getService();if (eventService != null) {rootNode = eventService.getRootInActiveWindow();}if (rootNode == null) {if (DEBUG)Log.e(TAG, "try to connect:" + i);i++;openAccessibilityServiceIfNotStart();SystemClock.sleep(500);} else {break;}}return rootNode;}


如下开启服务
private void openAccessibilityServiceIfNotStart() {openService(NAME);Intent intent = new Intent();intent.setClass(mContext, AccessibilityEventService.class);// If not start ,to startif (!mAssert.isMyServiceRunning(AccessibilityEventService.class.getName())) {mContext.startService(intent);}}

在上面用到了AccessibilityNodeInfoDumper这个class,为了加快界面遍历速度,将其中不可点击的控件进行过滤,这样使得得到的控件信息速度更快。
通过AccessibilityNodeInfoDumper将得到AccessibilityNodeInfo的数组数据。这样我们在编写脚本的时候不再写具体的坐标值,而是去将界面的文字或其它信息封装成点击方法,如下我们可以通过text来遍历nodes数组去找到相应的控件并点击:
/** *  * 2015-1-19 hwy *  * @param text *            the ui with the text to click * @param waitTime *            the wait time after clcik(ms) * @return */public boolean clickOnText(String text, int waitTime) {mWaitTime = waitTime;getNodes();if (infos == null || infos.size() == 0) {return false;}for (int i = 0; i < infos.size(); i++) {String title = infos.get(i).getText() + "";if (title.equals(text)) {return click(i);}}Log.e(TAG, "clickOnText false!");return false;}
当然还可以通过描述、id等方式去扩展,这样我们自动化测试软件的脚本适配难度将大大降低。




0 0
原创粉丝点击