Linux Monkey测试方案设计实现

Monkey测试常用与GUI压测,用来发现应用程序存在的bug。在Linux平台下,如果我们想用GUI压测的方式评估一个桌面环境的稳定性,也可以借鉴Monkey测试的思路,不过Linux平台下并没有一个开箱可用的方案,因此我做了一些探索尝试,总结如下,如有帮助,点个赞吧。(hhhh)

方案设计

父子进程分离

引入多进程的考量

  1. 增强健壮性,GUI压测进程异常退出时,父进程可以重启子进程。 (执行桌面环境级别的GUI压测的过程中,往往需要打开不限数量的应用程序,容易出现系统内存资源吃满的情况,这种情况下会触发Linux的OOM-Kill机制,OOM-Kill机制会基于OOM-Score指标,终止一些进程,来保证操作系统的可响应性。当OOM-Kill机制导致X11 Server实例重置时,GUI操作将无法执行,进程会因此退出。多进程架构可以通过父进程监控子进程的执行状态,把子进程重启,从而保证GUI压测能够持续进行。)

键鼠控制方案对比

xdotool:  GitHub - jordansissel/xdotool: fake keyboard/mouse input, window management, and more

pyautogui:  Welcome to PyAutoGUI’s documentation! — PyAutoGUI documentation

xdotool

pyautogui

是否支持Wayland××
支持键盘输入模拟
支持鼠标模拟
支持图像识别×
接口实现的方式基于C, X11 APIpython(Xlib)
Github Stars(2023/8/29)2.7k8.5k

从扩展性、社区繁荣度、功能完善度和开发成本几个维度考量,选择pyautogui作为键鼠控制方案。

Wayland兼容方案

Wayland协议相比X11更重视安全性,所以协议设计上突出强隔离性,事件的分发由compositor决定,每个client只能收到自己的事件,并且只有获得焦点的窗口才能接收键鼠事件。所以通用的GUI测试方案在Wayland上往往行不通。目前Linux社区里对Wayland下自动化GUI测试的支持,做的比较好的是KDE. KDE的KWayland设计实现了一个extension — FakeInput, 用于扩展支持模拟的键鼠输入。

代码仓库:https://github.com/KDE/kwayland

KDE那一层的关键源码参看src/client/fakeinput.cpp:

// 发送鼠标点击事件

void FakeInput::Private::sendPointerButtonState(Qt::MouseButton button, quint32 state)

{

    Q_ASSERT(manager.isValid());

    uint32_t b = 0;

    switch (button) {

    case Qt::LeftButton:

        b = BTN_LEFT;

        break;

    case Qt::RightButton:

        b = BTN_RIGHT;

        break;

    case Qt::MiddleButton:

        b = BTN_MIDDLE;

        break;

    default:

        // TODO: more buttons, check implementation in QtWayland

        // unsupported button

        return;

    }

        // fake-input协议接口

    org_kde_kwin_fake_input_button(manager, b, state);

}

其中关键的是 org_kde_kwin_fake_input_button .

org_kde_kwin_fake_input_button 并不是直接定义在项目源码中的接口,而是wayland-scanner基于xml文件生成的。

假设项目构建目录为./build, 则org_kde_kwin_fake_input_button 的源码在 build/src/client/wayland-fake-input-client-protocol.h.

/**

 * @ingroup iface_org_kde_kwin_fake_input

 */

static inline void

org_kde_kwin_fake_input_button(struct org_kde_kwin_fake_input *org_kde_kwin_fake_input, uint32_t button, uint32_t state)

{

    wl_proxy_marshal_flags((struct wl_proxy *) org_kde_kwin_fake_input,

             ORG_KDE_KWIN_FAKE_INPUT_BUTTON, NULL, wl_proxy_get_version((struct wl_proxy *) org_kde_kwin_fake_input), 0, button, state);

}

录制回放方案设计

用一个数据结构描述GUI操作,将该对象序列化后存储在本地磁盘,实现录制;回放时,将数据反序列化为事件对象并执行,实现回放。

录制文件的存储处理

Action数据的写入采用 “”即时写 “策略,即每一个数据做一次写入操作,这样做的好处:

  1. 避免action数据在内存中积压,导致内存资源过度占用;
  2. 避免测试过程中,进程异常导致数据丢失

保活机制

Monkey GUI压测过程中会出现桌面环境崩溃的异常,导致测试中断,针对这类异常,设计双重保活机制:

机制一:守护进程+负载控制

基本思路:

检查系统负载情况,适时释放系统资源。子进程退出后父进程能重启唤起。

机制二:lightdm自启动

将monkey测试嵌入到lightdm的启动流程中,修改/etc/lightdm/lightdm.conf配置文件。

 应用级别的Monkey Test机制

核心点
  • 应用启动
  • GUI事件过滤
  • 窗口管理
实现思路

应用进程的启动采用子进程唤起的方式。

GUI事件基于应用窗口的范围进行过滤。

实现应用级别的monkey测试,需要具备窗口管理的能力,核心接口:

基于窗口管理的接口,我们能做到:

  • 获取目标应用窗口的信息,进而实现事件过滤
  • 窗口管理(用于窗口位置、大小恢复)

窗口管理用到了一个开源库,参考:GitHub - Kalmat/PyWinCtl: Cross-Platform module to get info on and control windows on screen

如果觉得有用 ,请点个赞吧。Thanks♪(・ω・)ノ

  • 18
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时光机121906

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值