DirectFB压力测试工具


 


GUI应用程序自动测试一直是个难题,通常的做法就是先把人工测试过程录制下来,然后去重放这个测试过程。这种方法的主要缺点是很难自动检测运行结果的正确性,所以很多人都不屑去使用它。其实工具总是有它的局限性,它能不能发挥它应有的作用,还依赖于人的灵活运用。即不能过分依赖于工具,也不能盲目排斥工具。


在质量保证的过程中,人无疑是最重要的,没有什么比一次性写出高质量代码就有效的了。但事实是即使有良好的架构设计,辅之于单元测试和代码评审等一些有效实践,仍然有些BUG成为漏网之鱼,更何况很多团队这些工作做得并到位。单一工具和方法很难包医百病,但各种方法和工具综合起来使用的效果就大不一样了。


前段时间一位同事开发了一个GUI自动测试工具,我们把它用于BUG重现和压力测试中,取得了不错的效果。这里介绍一下DirectFB里面事件录制和重放的方法:


获得键盘设备:


DirectFB压力测试工具_测试工具dfb_input_enumerate_devices ((InputDeviceCallback)device_callback,

DirectFB压力测试工具_测试工具    &context->keyboard_device, DICAPS_KEYS);



获得鼠标或触摸屏设备:


DirectFB压力测试工具_测试工具dfb_input_enumerate_devices ((InputDeviceCallback)device_callback,

DirectFB压力测试工具_测试工具    &context->mouse_device, DICAPS_AXES | DICAPS_BUTTONS);



向设备注册事件监听函数:


DirectFB压力测试工具_测试工具dfb_input_attach (context->mouse_device,

DirectFB压力测试工具_测试工具    input_device_listener, context, &context->mouse_reaction);

DirectFB压力测试工具_测试工具dfb_input_attach (context->keyboard_device,

DirectFB压力测试工具_测试工具    input_device_listener, context, &context->keyboard_reaction);



事件监听函数:


DirectFB压力测试工具_测试工具static ReactionResult input_device_listener (const void *msg_data, void *ctx)

DirectFB压力测试工具_测试工具_10DirectFB压力测试工具_单元测试_11...{

DirectFB压力测试工具_单元测试_12    DFBContext *context = (DFBContext*)ctx;

DirectFB压力测试工具_单元测试_12    DFBInputEvent *event = (DFBInputEvent*)msg_data;

DirectFB压力测试工具_单元测试_12

DirectFB压力测试工具_单元测试_12    event->locks = 0;

DirectFB压力测试工具_单元测试_12    event->flags &= ~DIEF_LOCKS;

DirectFB压力测试工具_单元测试_12

DirectFB压力测试工具_单元测试_12    if (fwrite (msg_data, sizeof (DFBInputEvent), 1, context->file) != 1)

DirectFB压力测试工具_测试过程_19DirectFB压力测试工具_测试过程_20    ...{

DirectFB压力测试工具_单元测试_12        printf ("[%s]: fwrite Error errno = %d ", __func__, errno);

DirectFB压力测试工具_单元测试_12

DirectFB压力测试工具_单元测试_12        g_main_loop_quit (context->loop);

DirectFB压力测试工具_应用程序_24    }

DirectFB压力测试工具_单元测试_12    fflush(context->file);

DirectFB压力测试工具_单元测试_12

DirectFB压力测试工具_单元测试_12    return RS_OK;

DirectFB压力测试工具_测试工具_28}

DirectFB压力测试工具_测试工具


事件重放函数:


DirectFB压力测试工具_测试工具static gboolean replay_one_event (gpointer user_data)

DirectFB压力测试工具_测试工具_10DirectFB压力测试工具_单元测试_11...{

DirectFB压力测试工具_单元测试_12    DFBContext *context = (DFBContext*)user_data;

DirectFB压力测试工具_单元测试_12    off_t cur = 0;

DirectFB压力测试工具_单元测试_12

DirectFB压力测试工具_单元测试_12    DFBInputEvent event = context->event;

DirectFB压力测试工具_单元测试_12

DirectFB压力测试工具_单元测试_12    if(event.type == DIET_KEYPRESS || event.type == DIET_KEYRELEASE)

DirectFB压力测试工具_测试过程_19DirectFB压力测试工具_测试过程_20    ...{

DirectFB压力测试工具_单元测试_12        dfb_input_dispatch (context->keyboard_device, &event);

DirectFB压力测试工具_应用程序_24    }

DirectFB压力测试工具_单元测试_12    else

DirectFB压力测试工具_测试过程_19DirectFB压力测试工具_测试过程_20    ...{

DirectFB压力测试工具_单元测试_12        dfb_input_dispatch (context->mouse_device, &event);

DirectFB压力测试工具_应用程序_24    }

DirectFB压力测试工具_单元测试_12

DirectFB压力测试工具_单元测试_12    if (fread (&context->event, sizeof (DFBInputEvent), 1, context->file) == 1)

DirectFB压力测试工具_测试过程_19DirectFB压力测试工具_测试过程_20    ...{

DirectFB压力测试工具_单元测试_12        guint ms = (context->event.timestamp.tv_sec - event.timestamp.tv_sec) * 1000

DirectFB压力测试工具_单元测试_12            + (context->event.timestamp.tv_usec - event.timestamp.tv_usec)/1000;

DirectFB压力测试工具_单元测试_12

DirectFB压力测试工具_单元测试_12        g_timeout_add (ms, replay_one_event, user_data);

DirectFB压力测试工具_应用程序_24    }

DirectFB压力测试工具_单元测试_12    else

DirectFB压力测试工具_测试过程_19DirectFB压力测试工具_测试过程_20    ...{

DirectFB压力测试工具_单元测试_12        g_main_loop_quit (context->loop);

DirectFB压力测试工具_应用程序_24    }

DirectFB压力测试工具_单元测试_12

DirectFB压力测试工具_单元测试_12    return FALSE;

DirectFB压力测试工具_测试工具_28}

DirectFB压力测试工具_测试工具


注意:DirectFB中的笔点事件是以相对坐标方式表示的,所以要保证重放时光标在同样的初始位置。如果DirectFB以多进程的方式运行,这个程序可以是一个独立的进程,否则要放到应用程序的进程中才行。


~~end~~