自己主动化測试程序之中的一个自己定义键盘的模拟測试程序(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() [email protected] \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

时间: 2024-08-24 16:29:34

自己主动化測试程序之中的一个自己定义键盘的模拟測试程序(C语言)的相关文章

Selenium2 Python 自己主动化測试实战学习笔记(五)

7.1 自己主动化測试用例 无论是功能測试.性能測试和自己主动化測试时都须要编写測试用例,測试用例的好坏能准确的体现了測试人员的经验.能力以及对项目的深度理解. 7.1.1 手工測试用例与自己主动化測试用例 手工測试用例是针对手工測试人员.自己主动化測试用例是针对自己主动化測试框架.前者是手工測试用例人员应用手工方式进行用例解析,后者是应用脚本技术进行用例解析. 前者具有较好的异常处理能力,并且可以基于測试用例,制造各种不同的逻辑推断,并且人工測试步步跟踪,可以仔细定位问题.后者全然依照測试用例

【金阳光測试】大话Android自己主动化測试--Android自己主动化系列(1)--金阳光于2013年4月份

Android自己主动化測试框架和工具在四年多的发展日趋成熟. 从五年前的第一代自己主动化架构演进到眼下第四代(本系列讲座第7篇后将具体剖析第三代和第四代自己主动化框架)从曾经最早谷歌推崇的monkey随机測试工具到点触流自己主动化工具monkeyrunner.MonkeyTalk.基于元素识别的自己主动化框架sikuli.seeTest.iTest.基于控件识别的Robotium.SL4A.这三种技术各有千秋.基本上如今做出的自己主动化框架都是整合或者改动了以上这些免费的自己主动化框架:比方中

Python实战之自己主动化评论

Python实战之自己主动化评论 玩csdn博客一个多月了,渐渐发现了一些有意思的事,常常会有人用相同的评论到处刷.不知道是为了加没什么用的积分,还是纯粹为了表达楼主好人.那么问题来了,这种无聊的事情当然最好能够自己主动化咯.自己也来试了一把,纯属娱乐. 登陆 要评论当然要能够先进行登陆,採用 requests 库进行处理,尝试是否能看到自己的消息列表: msg_url ="http://msg.csdn.net/" r = requests.get(msg_url, auth=('d

程序只启动一个实例的几种方法

我们在使用<金山词霸>时发现,在<金山词霸>已经运行了的情况下,再次点击<金山词霸>的图标,那么它不会再运行另外一个<金山词霸>,而是将已有的<金山词霸>给激活,始终只能运行一个<金山词霸>的实例. 在我们的程序当中如果要实现类似<金山词霸>的功能,就要解决两个问题,首先是要判断该程序已有一个实例在运行,其次是要将已运行的应用程序实例激活,同时退出第二个应用程序实例.  对于第一个问题,我们可以通过设置命名互斥对象或命名信

Android自己主动化測试解决方式

如今,已经有大量的Android自己主动化測试架构或工具可供我们使用,当中包含:Activity Instrumentation, MonkeyRunner, Robotium, 以及Robolectric.另外LessPainful也提供服务来进行真实设备上的自己主动化測试. Android自身提供了对instrumentation測试的基本支持,当中之中的一个就是位于android.test包内的ActivityInstrumentationTestCase2类,它扩展了JUnit的Test

【金阳光測试】基于控件核心技术探讨---Android自己主动化系列(2)---2013年5月

第一讲分享了下安卓自己主动化一些概况和一些自己主动化框架现状和技术可以解决什么样的问题. 这次课就深入到android世界里面.遨游.翱翔.深入了解自己主动化測试核心技术. 搞过编程开发的同学听到instrumentation这个东西一定不陌生.在android架构里面分四层(最以下是硬件驱动相关抽象层.不是笔者讨论的内容范围),往上面一点是协议栈.也不是讨论的核心,都和c语言相关.一直到第三层框架层(framework). 细分有二: A.   android的改良虚拟机dalvik和Runt

Mock+Proxy在SDK项目的自己主动化測试实战

项目背景 广告SDK项目是为应用程序APP开发者提供移动广告平台接入的API程序集合,其形态就是一个植入宿主APP的jar包.提供的功能主要有以下几点: - 为APP请求广告内容 - 用户行为打点 - 错误日志打点 - 反作弊 团队现状 在项目推进的过程中.逐渐暴露了一些问题: 1. 项目团队分为上海团队(服务端)和北京团队(client),因为信息同步,人力资源等其它原因.服务端与client的开发进度非常难保持同步,经常出现client等着和服务端联调的情况 2. 接口文档不稳定,理解有偏差

Android自己主动化測试之Monkeyrunner用法及实例

眼下android SDK里自带的现成的測试工具有monkey 和 monkeyrunner两个.大家别看这俩兄弟名字相像,但事实上是完全然全不同的两个工具,应用在不同的測试领域.总的来说,monkey主要应用在压力和可靠性測试上,执行该命令能够随机地向目标程序发送各种模拟键盘事件流,而且能够自定义发送的次数,以此观察被測应用程序的稳定性和可靠性,应用起来也比較简单,记住那几个命令即可了.而monkeyrunner呢,相比之下会强大一些,它主要可应用于功能測试,回归測试,而且能够自定义測试扩展,

带有机器人框架的.NET自己主动化測试

Clayton Neal在软件測试和质量保证方面有超过13年的经验,当中有八年的Windows, web,和移动应用程序的測试自己主动化经验.他在測试领域的全部等级都工作过.近期他在Bloomberg and Misys担任QA经理.同一时候他还是Sogeti的自己主动化測试顾问.Clayton对自己主动化測试超迷恋,还见识了怎样亲自成功实施測试自己主动化. ? 測试自己主动化的优点我们都非常清楚,更快地反馈问题,降低手工測试,持续集成就是当中随口可举的.測试团队成员越多,公司使用自己主动化越多