我的配置是linux 64, android4.2.2的sdk。 实现的细节都在代码注释里了,变量名以及echo的内容也是说明的一部分。
主流程为:
- 检测是否指定端口的模拟器已经运行,若有则关闭
- 创建模拟器
- 启动模拟器
- 用ant build包,通过检查bin目录下有没有apk来确定是否成功
- 检查指定端口的模拟器是否已正常运行
- 用adb安装apk
- 启动apk的activity,让程序自己跑
- 用shell ps循环检测程序是否已退出,若已退出,检查是否sdcard是是否已成功生成报告文件
- 若报告文件不完整,即程序被中止/崩溃,重启activity
- 检测是否超时
#!/bin/bash # by hursing 2013-10-28 # 指定port,可以不干扰其它正在运行的模拟器。根据sdk文档,port可以在5554至5584之间,最好是偶数 portNumber=5578 emulatorPID=`ps -ef | grep "emulator" | grep "port $portNumber" | awk '{print $2;}'` if [ -n "$emulatorPID" ]; then echo "close emulator window" kill -9 $emulatorPID fi # 创建模拟器,force选项能覆盖已存在的模拟器,即sdcard内容也抹掉。echo no是回答不需要自定义硬件配置 echo "create avd" emulatorName="Test" echo no | android create avd --name $emulatorName --force --target android-17 --sdcard 300M --abi armeabi-v7a # 启动模拟器,port选项指定tcp端口。&是另起进程执行 echo "start avd" emulator -avd $emulatorName -port $portNumber & # 没有证书签名,所以是debug echo "build apk" android update project -p . ant debug if [ $? -ne 0 ]; then echo "build failed, try again now..." ant clean ant debug if [ $? -ne 0 ]; then echo "can NOT build apk!" exit 5 fi fi apkFile=`find ./bin/*.apk | grep -v "unaligned"` if [ -z "$apkFile" ]; then echo "no apk file generated!" exit 7 fi # wait-for-device能block住脚本直到不显示offline echo "check emulator ready..." emulatorSerialNumber="emulator-$portNumber" ready=`adb devices | grep "$emulatorSerialNumber"` if [ -z "$ready" ]; then echo "emulator can NOT launch." exit 3 else ready=`adb devices | grep "$emulatorSerialNumber.*offline"` if [ -n "$ready" ]; then echo "wait-for-device" adb -s $emulatorSerialNumber wait-for-device sleep 10 fi fi # 当adb可以安装时,模拟器未必已经初始化完成,还是会失败的,所以要检测error,试3遍。 echo "install apk" let maxTryTimes=3 while [ $maxTryTimes -gt 0 ]; do result=`adb -s $emulatorSerialNumber install $apkFile` # 'ant installd' can NOT specify device check=`echo "$result" | grep -o "Error"` if [ -z "$check" ]; then echo "successfully install apk" break; else echo "$result" echo "install failed, try again after sleeping 10 seconds" sleep 10 let maxTryTimes-=1 fi done if [ $maxTryTimes -eq 0 ]; then echo "can NOT install apk to emulator." exit 4 fi echo "start MainActivity" activityName="com.hursing.MainActivity" packageName=`cat AndroidManifest.xml | grep -o "package=\".*\"" | sed 's/package="//;s/"//'` adb -s $emulatorSerialNumber shell am start -W -n "$packageName/$activityName" heartBeat=10 echo "waiting for test finished.check every $heartBeat seconds." resultFile="/sdcard/result.txt" successFlag="End at " sleep $heartBeat let maxTimeLimit=60*10 while [ $maxTimeLimit -gt 0 ]; do running=`adb -s $emulatorSerialNumber shell ps | grep $packageName` if [ -n "$running" ]; then let maxTimeLimit-=$heartBeat echo "waiting, sleep another $heartBeat seconds..." sleep $heartBeat else report=`adb -s $emulatorSerialNumber shell cat "$resultFile"` check=`echo "$report" | grep -o "$successFlag"` if [ -z "$check" ]; then echo "app crash, run activity again..." adb -s $emulatorSerialNumber shell am start -W -n "$packageName/$activityName" else echo "app exit normally" break fi fi done echo "close emulator window." kill -9 `ps -ef | grep "emulator" | grep "port $portNumber" | awk '{print $2;}'` if [ $maxTimeLimit -eq 0 ]; then echo "Test timeout!" echo "$report" exit 9 else echo "Test Finished!" echo echo "$report" fi
java代码里有一点要注意,如果程序崩溃,弹出了"has stopped”对话框,那么ps还是能查到的,要自己调用
Thread.setDefaultUncaughtExceptionHandler
,在handler里直接System.exit(0)才行。
转载请注明出处:http://blog.csdn.net/hursing