Robotium通过广播与服务+shell命令实现跨进程自动化测试之shell命令篇

本来说是周末的时候想把shell篇整理出来的,结果,周六加班,加完班和朋友出去玩,礼拜天又偷了个懒,结果周末什么都没做,跟研发老大说准备的接口测试资料也没有准备好。。人生啊!到了礼拜一因为上线的缘故,加班到今天凌晨2点才到家里。。人生啊!所以今天赶紧上来把下篇写了,其实东西并不是很多。。匆忙整理,如有错误,欢迎指正。

上一篇博文写完了广播与服务,现在我们已经有了一个服务,服务里面注册了一个接收器,用来接收我们的广播信号,只要接收器匹配到了相应的广播信号,我们就开始onReceive中的代码。所以我们今天主要是介绍onReceive中有什么东西。

先来想象一个场景,我们写了一段测试注册的自动化的代码,注册的过程中需要添加头像——为了简单起见,我们只选择拍照——这时我们将跳出程序进到照相机,也就是所谓的跨进程了。此时robotium中的代码是不能被执行的,大致原因就是我们被测的APP进程被挂起,导致robotium一起被挂起了,所以接下去的东西都无法执行,除非再次回到APP。那么我们大致明白了,shell命令要做的事情就是完成整个的拍照,确认,剪辑动作,然后回到程序。shell命令的介绍在上篇博文中已经贴出网址。

所以我们这一块就两个东西:1.发送什么样的命令。2.收到命令后,如何执行。这两个问题也是我在实际实施的过程中碰到的问题,实际的完成过程实在让我汗颜,甚至有点难以启齿。。

最初在网上需找资料的时候,可以找到很多资料都是使用Runtime.getruntime().exec()来执行shell命令,但是没有一个有具体例子的,搞得我很烦躁,究竟应该是使用全部"adb shell input tap xxx xxx"还是直接用"input tap xxx xxx",有root权限的手机究竟要不要加"su",需要加的话又该在什么时候,什么地方加进去。。网上的答案没有一个有明确的说明的,可能是我搜索能力有限,总之我找了一天半的时间,没有找到。。在我接近崩溃的时候,我突然想到xuxu自己集成的一个测试包中也是利用shell命令来跨进程的,既然他也是利用shell,也是用java,那必然会有我要的答案。。急忙打开,很顺利的找到了一段代码suShell,在这里再次感谢xuxu,可怜这段代码躺在我的文件夹中两个多礼拜了,我就是想不起它,惭愧至极。下面这段代码不是我写的,我只是一个搬运工。

 1 private static void suShell(String cmd){
 2         try {
 3             Thread.sleep(2000);
 4         } catch (InterruptedException e) {
 5             e.printStackTrace();
 6         }
 7         Process ps = null;
 8         DataOutputStream os;
 9         try {
10             ps = Runtime.getRuntime().exec("su");
11             os = new DataOutputStream(ps.getOutputStream());
12             os.writeBytes(cmd + "\n");
13             os.writeBytes("exit\n");
14             os.flush();
15         } catch (IOException e) {
16             // TODO Auto-generated catch block
17             e.printStackTrace();
18         }
19     }

好吧,我承认线程暂停那段是我加上去的,因为不同手机启动相机的速度是不一样的。好啦,我纠结了一天半,现在分享出来,大家就不用这么麻烦了,也算一个好事(其实心里阴暗的不行),怎么执行有了,那就只剩下执行什么了!还好,一天半的搜索也不是什么都不知道对吧,好歹我知道这个命令就两个可能,要么是"adb shell input tap xxx xxx"要么就是"input tap xxx xxx",你要说还有swipe等等就当我没说好吗?我心里已经很阴暗了!挨个试就好了。。事实证明是后者。废话不多说了,贴代码。

在测试代码中我们先写一个方法出来:

1 private void sendBroad(String[] cmd){
2         Intent intent = new Intent();
3         intent.setAction("android.qwerty.action.open");
4         intent.putExtra("verify_code", cmd);
5         solo.getCurrentActivity().sendBroadcast(intent);
6     }

然后在测试用例里面:

1 String[] command = {"input tap 540 1700", "input keyevent 4"};
2 sendBroad(command);

接收到了广播,我们就剩下最后一个,在onReceive中实现我们的点击:

1 @Override
2         public void onReceive(Context context, Intent intent) {
3             for(String command:intent.getStringArrayExtra(flag)){
4                 suShell(command);
5             }
6         }

利用了foreach的循环,将数组中的每一个值都拿出来执行一次。换句话说,你想在相机中实现的操作,依次写进数组就可以了。

好了,到这里,我们的所有代码都实现了,跨进程也能很顺利的进行。。当然,我实现跨进程时是自己写了个小程序,在真正使用到公司的测试代码中的时候,还是出现了很多问题。这里就不说了。

整体来讲,代码是非常简单的,但是由于测试行业普遍的开发水平都比较低,会的人也没几个写了完整的教程的(我可以看成是敝帚自珍吗?),偶尔有几个写的也仅仅写了个思想大致完成要怎么做。所以搞得跨进程在测试行业好像很牛逼一样。。其实我从仅仅知道这个东西到自己完整的实现,也仅用了一周,如果不是中间卡壳了一天半,三天多点就能搞懂,如果你又是个有点Android技术的测试,我估计一两天你就能完成。。所以这东西很牛逼吗?其实并没有。。说了这么多也不知道自己说了啥。。就不说了哈哈。。

文章为本人原创,里面有很多说的不明白还有不正确的地方,但是创作不易,转载请务必声明,非常感谢。

时间: 2024-10-12 08:05:58

Robotium通过广播与服务+shell命令实现跨进程自动化测试之shell命令篇的相关文章

Robotium通过广播与服务+shell命令实现跨进程自动化测试之广播与服务

还记得当初刚学robotium的时候,有人提起过这个方法,当时觉得很牛逼,暂时不想接触(其实就是对比较深入,难以快速理解的知识的畏惧).现在到了不得不去了解的时候,也只能硬着头皮上了... 先来讲一下我现在对这个方法的理解:整个Android程序,我们可以看成是一个个的实验室(进程)组成的,我们使用robotium就转属于其中一个实验室,实验室的规定非常的严格,不允许人员进入其他的实验室.但是人总是要有些消息或者有些活动需要别的实验室配合(跨进程)..这个时候我们只有一种办法,就是通过中转人员(

Android四大组件——Service后台服务、前台服务、IntentService、跨进程服务、无障碍服务、系统服务

Service后台服务.前台服务.IntentService.跨进程服务.无障碍服务.系统服务 本篇文章包括以下内容: 前言 Service的简介 后台服务 不可交互的后台服务 可交互的后台服务 混合性交互的后台服务 前台服务 IntentService AIDL跨进程服务 AccessibilityService无障碍服务 系统服务 部分源码下载 前言 作为四大组件之一的Service类,是面试和笔试的必备关卡,我把我所学到的东西总结了一遍,相信你看了之后你会对Service娓娓道来,在以后遇

跳出Robotium单进程限制,实现跨进程调用的两种方式浅谈

用过Robotium做Android自动化测试的同学都知道,Robotium因为继承了instrumentation而无法进行跨进程的调用,比如模拟按键点击(据说4.3以后instrumentation有了getUIAutomator的入口,然后就木有然后了,本人没有亲试且不在本文讨论中). 本人亲试了两种实现方式,经实验均能实现简单的事件,比如:发送按键.点击.长按.拖动等,最终的调用方式都采用4.1以后的input命令实现,当然你得是root.具体命令如下: [email protected

开发调试linux服务时几个好用的进程和端口查询命令组合和简单脚本(ps netstat awk grep)

这几天在搭建flume服务并在其框架下开发,反复调试输入命令让人不厌其烦,因此在这里记录一下自己找到的一些小技巧: 首先,把自己的应用程序做成一个service是一个很好的选择,一个service就需要支持start 和 stop,start能启动程序,stop能找到start所启动的程序的进程并且关掉它. 可以直接根据/etc/init.d/下的服务脚本来改,但我遇到了问题:因为那些系统服务脚本都是基于start-stop-daemon命令,这个命令很强大,可以启动一个可执行文件并且把进程PI

linux下shell脚本执行方法及exec和source命令

exec和source都属于bash内部命令(builtins commands),在bash下输入man exec或man source可以查看所有的内部命令信息. bash shell的命令分为两类:外部命令和内部命令.外部命令是通过系统调用或独立的程序实现的,如sed.awk等等.内部命令是由特殊的文件格式(.def)所实现,如cd.history.exec等等. 在说明exe和source的区别之前,先说明一下fork的概念. fork是linux的系统调用,用来创建子进程(child

[android] 代码注册广播接收者&利用广播调用服务的方法

利用广播调用服务里面的方法,间接的方式调用服务内部的方法,与现实中差不多,请媒体曝光 主界面里面 在界面创建的时候开启一下服务普通的startService()方法 发送一条广播出去 获取Intent对象,通过new出来 调用Intent对象的setAction()方法,参数:一般就是包名 调用sendBroadcast(intebt)方法,发送广播,参数:Intent对象 服务里面 新建一个MyService类继承系统的Service类 添加一个自定义的服务的方法callServiceMeth

linux常用命令整理(五):shell基础

大家好,我是会唱歌的程序猿------ 最近在学习linux,闲暇之余就把这些基本的命令进行了整理,希望大家能用的上,整理的的目的是在忘了的时候翻出来看看^?_?^,前后一共分为五个部分: linux基本命令整理(一):常用命令 地址:http://www.cnblogs.com/devinCat/p/7247824.html linux基本命令整理(二):用户.用户组.文件系统和网络 地址:http://www.cnblogs.com/devinCat/p/7247847.html linux

Android应用开发基础之广播与服务(二)

服务两种启动方式 startService:服务被启动之后,跟启动它的组件没有一毛钱关系 bindService:跟启动它的组件同生共死 绑定服务和解绑服务的生命周期方法:onCreate->onBind->onUnbind->onDestroy 找领导办证 把服务看成一个领导,服务中有一个banZheng方法,如何才能访问? 绑定服务时,会触发服务的onBind方法,此方法会返回一个Ibinder的对象给MainActivity,通过这个对象访问服务中的方法 绑定服务 Intent i

Android 广播、服务、数据库、通知、包原理及描述

简介 在Android中运用了很多机制,例如:广播.服务.数据库.通知.包--等等.        什么是广播?Broadcast是一种广泛运用的在应用程序之间传输信息的机制.类似广播电台,根据特定频率来接收发送. 什么是服务?Service是android 系统中的四大组件之一,它跟Activity级别一样,但不能自己运行只能后台运行,并且可以和其他组件进行交互.使用场合例如:后台音乐播放器.         使用了什么数据库?在android中使用了开源项目sqlite操作数据. SQLit