因为我们假设程序的运行对我们来说是黑盒的,所以下面我们增加timer的机制来增强整个软件的健壮性。
假设系统提供如下伪函数(假设time的单位为ms毫秒)
//申请timer handle time_handle register_once_timer(int time_count,func callback_fun); //重启timer handle,此函数用于避免重复申请导致资源消耗 bool restart_once_timer(time_handle th, int time_count,func callback_fun); |
有上面的基础,我们实现系统的主要函数:
void ItemTimerStart(int time_count) { static time_handle ItemTimerId = 0; if(0 == ItemTimerId ) { ItemTimerId = register_once_timer (time_count,(func)ItemHandler); } else { restart_once_timer (ItemTimerId, time_count,(func)ItemHandler); } } |
同理step的实现如下:
void StepTimerStart(int time_count) { static time_handle StepTimerId = 0; if(0 == StepTimerId ) { StepTimerId = register_once_timer (time_count,(func)StepHandler); } else { restart_once_timer (StepTimerId , time_count,(func)StepHandler); } } |
假设我们的step是使用screen id来进行判定的,并假设系统提供如下伪函数来获取当前场景id int GetScreenID(void);
以此和timer为基础,优化上述handler如下:
void ItemHandler(void) { ItemTimerStart(30*60*1000);//设定30分钟超时,用于测试项出现不可预料异常不能正确完成时重启测试项测试 items[i].DeInit(); i++; if(i>ItemNum)i=0; items[i].Init();//或者应命名为entry s=1;//reset step index } void StepHandler(void) { switch(i) { case ItemX: switch(s) { case StepX: { if(XXXX_ScreenID == GetScreenID()) {//程序正确运行到此场景 //do something let step going on s++; StepTimerStart(5*1000);//5秒后检测是否执行到下一状态 } else {//程序还没有运行到此场景,则继续等待 //此处没有对s进行++ StepTimerStart(1000);//每1秒检测一次状态 } } break; …… case StepEnd: {//表示执行到了最好一步 ItemTimerStart(10);//立即切换至下一项测试 } break; } break; …… } } |
当然,里面每一项step切换到下一step需要等待的时间最好分具体情况来确定。
此策略的优点在于,用户任意的操作或者 系统其他的事件干扰都不会打断自动测试流程,直到用户手动关闭该软件。