您的位置:首页 > 移动开发 > Android开发

控制Android自动化测试程序的稳定性

2016-03-09 17:10 519 查看
在大量和长期的自动化测试中,如果你要使你的测试程序稳定运行,增强其永远不能被杀掉的功能是重中之重,特别是测试压力测试过程中,在极限条件下,如何确保测试程序不会被系统自带的处理机制给kill是非常重要的。

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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: