本来说是周末的时候想把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技术的测试,我估计一两天你就能完成。。所以这东西很牛逼吗?其实并没有。。说了这么多也不知道自己说了啥。。就不说了哈哈。。
文章为本人原创,里面有很多说的不明白还有不正确的地方,但是创作不易,转载请务必声明,非常感谢。