近期研究了如何进行埋点的自动化测试。主要实现思路为使用robtium在Android客户端上执行相应的操作,然后通过访问sensordata的接口将数据库中的埋点数据进行比对。实现过程中原本打算在运行robtium时通过手机访问数据库,但后来发现使用手机访问数据库较为困难且稳定性较差,于是修改成在java文件中通过使用adb shell命令启动Android程序,再对数据库进行访问。

最常用的做法是:

String cmd = ‘adb’ //cmd中为使用的adb指令
Process p;
p = Runtime.getRu=ntime().exec(cmd);

例如,想在java文件中使用adb指令将文件复制到手机上:

public static void pull(){
String cmd="adb push /User/huangxiaogua/Download/appium"; //appium是一个文件夹
Process p;
try {
p = Runtime.getRuntime().exec(cmd);
System.out.println("------------:>>>>>>");
p.waitFor();
if(sc.hasNext())
System.out.println(sc.next());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

学习过程中使用了waitFor()函数,此函数用于阻塞后续的程序,只有在process执行结束后才允许继续运行后续的代码。比如若我在调用了adb指令来执行安卓程序之后添加了访问数据库的语句如:

String sql = "select event,distinct_id,reason,$os from events where event='push' and distinct_id='u:2002050' order by time desc limit 1";
JSONObject josnResult = Fun.getResultFromSD(sql, token, project);
System.out.println(josnResult.get("event"));
System.out.println(josnResult.get("user_id"));
System.out.println(josnResult.get("reason"));
System.out.println(josnResult.get("$os"));

这样程序会在process还没有运行完的时候就执行数据库查询语句,而这个时候可能设备上还没有执行到能够产生数据的那一步就开始验证了,就会产生错误。此时waitFor()函数就很重要了,这是题外话。

遇到的问题

在java文件中调用adb指令时遇到了一点小插曲。刚开始我的程序是这样的:

String cmd = "adb shell am instrument -e class com.xsltest.datatest.test -w com.xsltest.framework/com.xsltest.framework.MyTestRunner";
Process p = Runtime.getRuntime().exec(cmd);

运行后eclipse就报错了,报如下的错误:

java.io.IOException: Cannot run program "adb": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1041)
at java.lang.Runtime.exec(Runtime.java:617)
at java.lang.Runtime.exec(Runtime.java:450)
at java.lang.Runtime.exec(Runtime.java:347)
at main.execAdb(main.java:14)
at main.main(main.java:40)

很奇怪,明明adb的环境变量已经配置好了,为什么还说没有adb这个指令呢?好吧,那我再配置一次adb的环境变量

1.找到android sdk的本地路径XXXX

2.打开终端输入

touch .bash_profile
open -e .bash_profile

3.添加路径

.bash_profile打开了,我们在这里添加路径。如果打开的文档里面已经有内容,我们只要之后添加;XXXX(注意前面一定要用分号隔开),如果是一个空白文档的话,我们就输入一下内容export PATH=${PATH}:XXXX。保存,关掉这个文档,

4.终端输入命令 source .bash_profile

5.终端输入命令 adb点回车,如果未显示command not found,说明此命令有效,环境便亮设置完成

经检查发现adb的环境变量是配置好的,那么到底是哪里出了问题呢?这个时候就要求助谷歌了。终于,有一位谷歌大大告诉我:java虚拟机加载的时候没有adb相关的环境变量,如果执行adb的命令,建议在设定命令的参数里面使用全路径。

那么此时我的程序就要变成:

String cmd = "/Users/huangxiaogua/Downloads/monkey2/XSL_Monkey/adb_mac/adb shell am instrument -e class com.xsltest.datatest.test -w com.xsltest.framework/com.xsltest.framework.MyTestRunner";
Process p = Runtime.getRuntime().exec(cmd);

运行了之后报给我Permission denied的错误,这好办,设置权限就好了

进入adb文件所在的目录下,运行

chmod 777 adb

再运行一遍,就能够跑通啦~!