[Effective WX] wx的UI UnitTest explained

本文深入探讨了wxUIActionSimulator在wx2.9.4中的实现,包括其在不同平台(如Windows和Linux)上的API使用,以及如何通过模拟鼠标和键盘事件来进行UI单元测试。此外,文章还详细介绍了事件循环的工作机制以及测试应用如何通过主动发送和接收事件来定制流程,实现事件驱动的UI测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在wx2.9.4中,wx支持了UI UnitTest。我们来看下这个framework是如何实现的UI UnitTest

1. wxUIActionSimulator类
wxUIActionSimulator类利用不同平台的API(windows:win32api, linux: X11)实现了基本事件发送机制。

1). 鼠标相关事件, 2). 键盘按键相关事件
    bool MouseMove ( long x , long y);
    bool MouseMove ( const wxPoint & point ) { return MouseMove ( point. x , point . y); }

    bool MouseDown ( int button = wxMOUSE_BTN_LEFT );
    bool MouseUp ( int button = wxMOUSE_BTN_LEFT );

    // Higher level interface, use it if possible instead
    bool MouseClick ( int button = wxMOUSE_BTN_LEFT );
    bool MouseDblClick ( int button = wxMOUSE_BTN_LEFT );
    bool MouseDragDrop ( long x1 , long y1, long x2 , long y2 ,
                       int button = wxMOUSE_BTN_LEFT );


    // Keyboard simulation
    // -------------------

    // Low level methods for generating key presses and releases
    bool KeyDown ( int keycode , int modifiers = wxMOD_NONE )
        { return Key ( keycode, modifiers , true ); }

    bool KeyUp ( int keycode , int modifiers = wxMOD_NONE )
        { return Key ( keycode, modifiers , false ); }

    // Higher level methods for generating both the key press and release for a
    // single key or for all characters in the ASCII string "text" which can currently
    // contain letters, digits and characters for the definition of numbers [+-., ].
    bool Char ( int keycode , int modifiers = wxMOD_NONE );

    bool Text ( const char *text );

在windows平台上,实现文件是src/msw/uiaction.cpp
在gtk平台,是利用x11提供的接口: src/unix/uiactionx11.cpp
另外common/uiactioncmn.cpp文件实现了一些基本公共函数.

2. 关于event loop
一个APP有一个main event loop,同时任何一个ShowModal所产生的window都会有一个active event loop。
在unit test app中,这个app并没有创建自己的main event loop,因为main event loop是在OnRun调用被创建的,但是这个test app并没有借用默认的OnRun,而是自己实现了OnRun,从而运行CPPUnit的run函数.

3. 两者结合实现UI的unit test
测试代码通过自己发送自定义事件,然后自己接收,来实现定制流程的event-driven ui test:

那么test app如何做到事件转发和处理的呢?以下代码段完成了这种机制:
     wxUIActionSimulator sim;

    // Add some extra distance to take account of window decorations
    sim .MouseMove ( m_button-> GetScreenPosition () + wxPoint (10, 10));
    sim .MouseClick ( wxMOUSE_BTN_LEFT );

    // Process the resulting button event
    wxYield ();

bool wxYield()
{
    return wxTheApp && wxTheApp-> Yield ();
}

bool wxAppConsoleBase ::Yield ( bool onlyIfNeeded )
{
    wxEventLoopBase * const loop = wxEventLoopBase :: GetActive();
    if ( loop )
       return loop -> Yield( onlyIfNeeded );

    wxScopedPtr <wxEventLoopBase > tmpLoop ( CreateMainLoop ());
    return tmpLoop -> Yield( onlyIfNeeded );
}

wxEventLoopBase::Yield函数将会调用Pending/Dispatch函数,来获取事件然后进行处理。

所以这种事件触发和接收方式,完全是客户端代码主动意愿的。什么时候发送事件和处理事件,全部由测试程序代码决定。

每一个event loop在调用它的Run函数开头,都会将设置自己为Actived EventLoop,代表自己是当前的event loop,这种用法在ShowModal被采用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值