控制Android自动化测试程序的稳定性
2016-03-09 17:10
519 查看
在大量和长期的自动化测试中,如果你要使你的测试程序稳定运行,增强其永远不能被杀掉的功能是重中之重,特别是测试压力测试过程中,在极限条件下,如何确保测试程序不会被系统自带的处理机制给kill是非常重要的。
修改服务Flags;首先把服务启动时候的OnStartCommond的flags修改为:START_STICKY,这儿的flags有几种参数
1、START_STICKY
在运行onStartCommand后service进程被kill后,那将保留在开始状态,但是不保留那些传入的intent。不久后service就会再次尝试重新创建,因为保留在开始状态,在创建 service后将保证调用onstartCommand。如果没有传递任何开始命令给service,那将获取到null的intent。
2、START_NOT_STICKY
在运行onStartCommand后service进程被kill后,并且没有新的intent传递给它。Service将移出开始状态,并且直到新的明显的方法(startService)调用才重新创建。因为如果没有传递任何未决定的intent那么service是不会启动,也就是期间onstartCommand不会接收到任何null的intent。
3、START_REDELIVER_INTENT
在运行onStartCommand后service进程被kill后,系统将会再次启动service,并传入最后一个intent给onstartCommand。直到调用stopSelf(int)才停止传递intent。如果在被kill后还有未处理好的intent,那被kill后服务还是会自动启动。因此onstartCommand不会接收到任何null的intent。
服务放到前台;经过长时间的经验得出来,如果要保证服务的稳定性,放到前台是最有效的方法,
首先我们需要在Service中创建Hanlder控制测试流程:
从Scheme(测试环境配置) → RunTest→EndTest
Android后台服务处理机制
如果是Android的测试程序,一般我们会用Android的Service这个组件去实现,所以Service是属于后台程序,Android会在几种情况下触发服务的kill机制低内存
当系统处于低内存下时,Android会优先杀掉低优先级的进程,这个我们可以通过提高优先级来避免,在manifest加入:android:priority="1000"当然最好的方式还是要避免出现低内存的情况,因为自动化测试需要一个稳定的测试环境保证每次的测试一致,如果在测试过程中出现了低内存,可以检查下是不是系统的某个测试场景有内存泄露情况。
运行时间过长
当测试程序运行时间过长时,会莫名其妙的自己断开了服务或者自己重启了服务,这儿可能也是省电保护那块做的处理,如何保证服务不断开,可以用如下的方法:修改服务Flags;首先把服务启动时候的OnStartCommond的flags修改为:START_STICKY,这儿的flags有几种参数
1、START_STICKY
在运行onStartCommand后service进程被kill后,那将保留在开始状态,但是不保留那些传入的intent。不久后service就会再次尝试重新创建,因为保留在开始状态,在创建 service后将保证调用onstartCommand。如果没有传递任何开始命令给service,那将获取到null的intent。
2、START_NOT_STICKY
在运行onStartCommand后service进程被kill后,并且没有新的intent传递给它。Service将移出开始状态,并且直到新的明显的方法(startService)调用才重新创建。因为如果没有传递任何未决定的intent那么service是不会启动,也就是期间onstartCommand不会接收到任何null的intent。
3、START_REDELIVER_INTENT
在运行onStartCommand后service进程被kill后,系统将会再次启动service,并传入最后一个intent给onstartCommand。直到调用stopSelf(int)才停止传递intent。如果在被kill后还有未处理好的intent,那被kill后服务还是会自动启动。因此onstartCommand不会接收到任何null的intent。
@Override public int onStartCommand(Intent intent, int flags, int startId) { flags = START_STICKY; return super.onStartCommand(intent, flags, startId); }
服务放到前台;经过长时间的经验得出来,如果要保证服务的稳定性,放到前台是最有效的方法,
@Override public void onStart(Intent intent, int arg1) { super.onStart(intent, arg1); // StartForeground Notification notification = new Notification(R.drawable.icon, getText(R.string.app_name), System.currentTimeMillis()); Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, getText(R.string.app_name), getText(R.string.txt_running), pendingIntent); startForeground(1, notification); }
选择更适合自动化测试的实现方法
要保证服务的运行,使用handler来控制线程之间的消息传递从而来保证测试序列的稳定运行。首先我们需要在Service中创建Hanlder控制测试流程:
从Scheme(测试环境配置) → RunTest→EndTest
class TestHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { // Scheme before test case START_SCHEME: schemeNumber = 0; // 这儿执行公共的测试环境预置程序,如设置开关、状态、填充等操作 mHandler.sendEmptyMessage(RUN_SCHEME); break; case RUN_SCHEME: if (schemeNumber == StaticData.chooseArray.length) { mHandler.sendEmptyMessage(END_SCHEME); } else { if (StaticData.chooseArray[schemeNumber]) startScheme(schemeNumber); else { schemeNumber++; mHandler.sendEmptyMessage(RUN_SCHEME); } } break; case END_SCHEME: mHandler.sendEmptyMessageDelayed(START_TEST, 2000); break; case START_TEST: // init test number testNumber = 0; // start run mHandler.sendEmptyMessage(RUN_TEST); break; case RUN_TEST: if (null == StaticData.runList) { return; } if (testNumber == StaticData.runList.size()) { if (StaticData.runState.equals("circle")) { testNumber = 0; mHandler.sendEmptyMessageDelayed(RUN_TEST, 3000); } else { StaticData.testFinishEvent = getResources().getString(R.string.txt_finish_case); mHandler.sendEmptyMessageDelayed(END_TEST, 3000); } } else { StaticData.runList.get(testNumber); StaticData.caseNumber = StaticData.runList.get(testNumber).runCaseNumber; int caseTime = StaticData.runList.get(testNumber).runNumber; // start startRunCase(StaticData.caseNumber, caseTime); } break; case END_TEST: stopSelf(); android.os.Process.killProcess(android.os.Process.myPid()); break; } } };然后在每一次用例的执行的时候新建一个Thread运行具体的测试步骤及可,在执行结束的时候再发消息给handler表示可以执行下一条用例了,具体程序如下:
// read txt // 1 time=5 minutes private void testCase_1(final int caseTime) { Thread currentThread = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < caseTime; i++) { mFunction.killAllActivities(); mOperate.sleep(2000); File file = new File(StaticData.TEXT_URL); Uri uri = Uri.fromFile(file); Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); intent.addCategory("android.intent.category.DEFAULT"); intent.setDataAndType(uri, "text/plain"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setPackage("com.android.reader"); mContext.startActivity(intent); mOperate.sleep(3000); mNodeOperate.clickOnText(stringArray[0], 2000); mNodeOperate.clickOnText(stringArray[1], 2000); mNodeOperate.clickOnText(stringArray[2], 2000); mNodeOperate.clickOnText(stringArray[3], 2000); long startTime = System.currentTimeMillis(); while (!Time.isTimeOver(startTime, 5)) { clickAlertWindow(); mOperate.clickOnScreen(Global.SCREEN_WIDTH - 100, Global.SCREEN_HEIGHT / 2); mOperate.sleep(10000); } mOperate.sendKeyDownUpSync(KeyEvent.KEYCODE_HOME); mOperate.sleep(2000); } // end case // print log mEventHandler.sendEmptyMessage(PRINT_LOG); } }); currentThread.start(); }
相关文章推荐
- android 使用ViewDragHelper高仿QQ主界面效果
- Android下拉刷新、滚动到底部自动加载更多RecyclerView组件
- Android studio问题汇总
- Android开发环境搭建(windows环境下)
- android差异化更新(增量更新)
- Adapter模式实战-重构鸿洋的Android建行圆形菜单
- “煎蛋”Android版的高仿GitHub路径
- ExpandableListView的使用
- Android统计图表MPAndroidChart
- Android 数据库管理— — —升级数据库
- Android 把图片进行压缩
- android支持多行的radiogroup
- Android学习之Timer和TimerTask
- 注册谷歌帐号以及用其他镜像解决android sdk的下载问题(已解决)
- Android消息推送解决方案
- 41.Android之图片放大缩小学习
- Android开发中java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}: java.lang.NullPoi
- android开机启动Service
- Android-SDK-Windows的sdk manager闪退
- Android 数据库管理— — —创建数据库