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

在大量和长期的自动化测试中,如果你要使你的测试程序稳定运行,增强其永远不能被杀掉的功能是重中之重,特别是测试压力测试过程中,在极限条件下,如何确保测试程序不会被系统自带的处理机制给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();
	}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值