自動化測試程序之一自定義鍵盤的模擬測試程序(C語言)

一、測試程序編寫說明
我們做的終端設備上運行的是QT應用程序,使用自定義的鍵盤接口。經過測試人員長時間的人機交互測試,來確認系統的功能是否滿足需求。現在需要編寫一個自動化的測試程序,能夠按照預設的腳本執行,比如某個按鍵需要連續執行10000次,或是通過連續幾個按鍵動作執行特定的業務流程10W次。通過這樣的自動測試,可以減輕測試人員的負擔,還可以查看觸發N次按鍵後,畫面執行N次後的系統的穩定性,如內存使用率,cup使用率等等。

設備有4*4的鍵盤,包括0-9,C(Call),A,U(up),D(Down),F1,F2功能鍵,屏幕的不同畫面上根據前述按鍵的動作執行相應的響應動作。

二、測試程序的結構分析

根據上述的簡單要求,先分析測試程序的結構如下:

讀入的腳本文件可以是TXT文件大概結構如下:

   --------Script_Sample.txt------------
3
A 5
R 3 2
U 5
C 6
A 3

其中的第一行表示以下執行的5個動作,分別是按A 、U、C、A鍵並且每次按鍵後休息相應的秒數(即後面的數值),其中的R 5 1 行表示以下1行重複再重複5次。腳本文件中R可不寫;若不寫,表示依次順序執行,沒有循環操作。

測試程序根據這個腳本構造一個鏈表,鏈表中的節點表示相應的操作,操作序列中循環動作再列表中構成局部的單向循環列表。

三、測試程序實現主要邏輯
1、定義鏈表


typedef struct List  
{  
    char operation;
    int  seconds;
    FLAG c_flag;
    int  i_repeatCnt;
    int  i_repeatLines;
    struct List *nextGp; //指針域  
    struct List *nextMemeber; //指針域  
}List;  
List *oprtData_Set;

2、上報輸入事件


int reportkey(int fd, uint16_t type, uint16_t keycode, int32_t value)  
{  
    struct input_event event;  

    event.type = type;  
    event.code = keycode;  
    event.value = value;  

    gettimeofday(&event.time, 0);  

    if (write(fd, &event, sizeof(struct input_event)) < 0) {  
        printf("report key error!\n");  
        return -1;  
    }  

    return 0;  
} 

3、使用尾插法按照腳本中的動作構造按鍵動作的鏈表


void TailCreatList(List *L,char * fname)  //尾插法建立鏈表  
{  
    List *tmpData;
    List *tail ;
    List *groupheader;  

    int i_repeatNums = 0;
    int i_repeatLines = 0 ,i_repeatLines_tmp = 0;
    char c_repeatID;
    FLAG  flag = HEADER;//flag = 1 header
    char buffer[512];
    char c_repeatFlag;
    FILE *infile;
    infile=fopen(fname,"r");

    tail=L;  //NULL
    groupheader=tail->nextGp;//NULL

    if(infile==NULL)
    {
        printf("\nFailed to open the file : %s \n",fname);
        exit(0);
    }
    else
    {
        printf("open success! \n");
    }

    fgets( buffer, sizeof(buffer), infile );
    sscanf( buffer,"%d",&i_stepMaxNum);
    printf("i_stepMaxNum = %d \n",i_stepMaxNum);
    memset(buffer,0,sizeof(buffer));
    while ( fgets(buffer, sizeof(buffer), infile))
    {

            tmpData=(struct List*)malloc(sizeof(struct List));
            if(!tmpData)
            {   
                printf("malloc() error@TailCreatList \n");
                exit(0);
            }
            memset(tmpData,0,sizeof(struct List));
            tmpData->nextMemeber=NULL;
            tmpData->nextGp=NULL;

            sscanf(buffer,"%c",&c_repeatFlag);

            if(c_repeatFlag == 'R')
            {
                sscanf( buffer,"%c %d %d",&c_repeatID,&i_repeatNums,&i_repeatLines );
                printf( "Repeat = %c , RepeatNums = %d,RepeatLines = %d \n",c_repeatID,i_repeatNums,i_repeatLines );
                memset(buffer,0,sizeof(buffer));
                continue;
            }
            else
            {

                sscanf( buffer,"%c %d",&(tmpData->operation),&(tmpData->seconds));
                printf( "Operation = %c , seconds = %d\n",tmpData->operation,tmpData->seconds);

                if(i_repeatLines > 0)
                {
                    if(flag==HEADER)
                    {
                        groupheader=tmpData;
                        tmpData->c_flag=flag;
                        tmpData->i_repeatCnt = i_repeatNums;
                        flag = MEMBER;
                        tmpData->nextMemeber=groupheader;
                        tmpData->nextGp=NULL;
                        tail->nextGp=tmpData; // 注意連接臃絞?每個Group的頭 用 nextGp 指針連接
                    }
                    else
                    {

                        tmpData->c_flag=flag;
                        tmpData->nextMemeber=groupheader;
                        tmpData->nextGp=NULL;
                        tail->nextMemeber=tmpData; //group中的成員用 nextMemeber 指針相連
                    }



                    tail=tmpData; //修改尾指針的位置。


                    i_repeatLines--;

                }
                else
                {  //--OK!!
                    flag=HEADER;
                    groupheader = tmpData;
                    tmpData->c_flag = flag;
                    tmpData->nextMemeber=groupheader;
                    tmpData->nextGp=NULL;
                    tail->nextGp=tmpData;
                    tail=tmpData;
                }
                if(i_repeatLines==0)
                {
                    flag=HEADER;    
                }
            }                    

        memset(buffer,0,sizeof(buffer));
    }
    tail->nextGp=NULL; 
    //tail->nextMemeber=NULL;

    fclose(infile);

    return ;

}

4、構造鍵盤事件,包括按下和擡起

void PressKeyEvent(char operation, int seconds)
{
    uint16_t keycode;

    printf("Key-%c ,%3d Sec |",operation,seconds);
    keycode = KeyToVal(operation);
    reportkey(KB_Fd, EV_KEY, keycode, KEYDOWN);  
  reportkey(KB_Fd, EV_KEY, keycode, KEYUP);  
    sleep(seconds);
}

5、按照鏈表中的數據逐條發送按鍵事件


void EmitEvent_Test(List *L)  
{  
    List *p=L->nextGp; 
        int loop=0;
        CYCLE_MODE mode_flag = FirstCycle;
        printf("-------EmitEvent_Test-------\n");

    while(p!=NULL)  
    {           
        //printf ("[** %d **,%c,%d,%d]  ",p->c_flag, p->operation,p->seconds,p->i_repeatCnt); 

        PressKeyEvent(p->operation,p->seconds);

            if(p->nextMemeber->c_flag != HEADER) // 
            {   
                p = p->nextMemeber;

            }
            else
            {
              /*
                    printf("p->nextMemeber Node is [** %d **,%c,%d,%d ]",
                        p->nextMemeber->c_flag, 
                        p->nextMemeber->operation,
                        p->nextMemeber->seconds,
                        p->nextMemeber->i_repeatCnt); 
                */


                    if(mode_flag == FirstCycle &&  p->nextMemeber->i_repeatCnt >0)
                    {   

                    loop = p->nextMemeber->i_repeatCnt;
                        mode_flag = OtherCycle;
                        p = p->nextMemeber;
                        loop--;
                        printf("\n----------------\n");
                        continue;
                    }


                if( loop > 0 && mode_flag == OtherCycle )//未重複完
                    {
                        p = p->nextMemeber;
                        loop--;
                        printf("\n----------------\n");
                        continue;

                    }

                    mode_flag = FirstCycle;//恢復默認值
                    p = p->nextGp;
                    printf("\n\n");

            }

    }  

}

四、參考源碼程序

http://download.csdn.net/detail/flyeagle022/8799555

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章