Page 108 - 《软件学报》2025年第5期
P. 108

2008                                                       软件学报  2025  年第  36  卷第  5  期


                 延迟移除, 在   C、C++、Rust 等语言测试用例集上的实验也验证了他们的方法效果.
                    与以上这些工作不同, 安卓界面测试的测试用例基本没有编程语言规则约束, 但由于其用例执行耗费时间长,
                 因此, 安卓测试用例执行对于其用例回放、错误理解与修复都至关重要. 近些年有一些针对安卓测试用例的约减
                 工作被提出, Jiang  等人  [16] 认为安卓测试序列是由很多小会话组成, 每个小会话又包含几个独立操作事件, 这些事
                 件的会话构成了测试用例约减的自然边界, 因为它们通常可以以高概率一起被约减, 因此他们利用分层结构对这
                 些会话进行建模, 并在此基础上完成测试用例约减. Sui 等人                [18] 则从当前执行过程中获取当前屏幕界面            XML  信
                 息, 并分析不同界面状态之间的差异来构建程序运行状态图, 并寻找图中最短路径算法作为约减序列. 此外, 为了
                 有效记录大量事件执行的         GUI 状态, 他们还提出了基于滑动窗口的自适应模型来有选择性地注入界面状态检测.
                 Yan  等人  [19] 通过对  Monkey  生成的测试序列进行手动分析, 定义了无操作、单一和组合无效果事件                  3  种类型的无
                 效事件, 并为其设计了       9  种约减规则, 此外, 他们还提出了一种静态界面状态层次树引导的测试序列约减方法.
                 Choi 等人  [26] 提出了一种启发式的对安卓测试套件         (test suite) 进行约减的方法, 他们定义了    3  种可被直接约减的测
                 试用例冗余模式: 对程序代码及界面覆盖率均无影响的测试用例、测试用例内对覆盖率无影响的环路、测试用例
                 间共享的子测试序列.
                    此外, 安卓测试用例复现会面临不确定性问题, 例如动态布局、弹出窗口、网络连接状态改变等, 这些将会导
                 致用例复现失败, Clapp    等人  [17] 提出了一种生成小测试事件集来大概率到达预期活动页面的技术, 从而可并非处
                 理增量测试中对子序列集的挑选及验证, 以提升约减效率. Jiang                等人  [27] 则结合确定性回放工具来处理测试序列约
                 减中可能会出现的不确定性情况, 并结合事件分组的方式缩短约减时间.
                    目前对安卓测试用例约减的工作仅从界面状态层次对事件进行分析, 并没有考虑操作事件对程序内部状态的
                 作用, 此外, 目前工作均仅从单一粒度对界面状态建模, 使得方法的通用性不强, 生成的测试序列存在过长或无法
                 约减的问题, 我们的工作则从控件粒度、页面布局粒度上分别对测试序列进行约减, 并且结合了静态数据流分析
                 对操作事件对程序内部状态的影响进行了标记.

                 2   动机示例

                    LibreNews 是一款突发新闻通知的安卓开源软件, 它允许用户自定义新闻消息来源, 并且可进行通知频率、
                 自动更新与否等方面的个性化设置. 图            1  给出了来自   LibreNews 应用的两个触发程序崩溃的测试序列. 序列            (a) 共
                 包含  48  个事件, 其最短路径包括      3  个事件: 打开应用后点击“GO TO LIBRENEWS”按钮进入应用主页             (  e 60  ), 然后
                 按下后退按钮     (  e 81  ), 程序页面并未发生变化, 然后点击“Automatically refresh”按钮  (  e 82  ), 程序崩溃. 序列  (b) 共包
                 含  124 个事件, 其最短路径包括     5 个事件: 打开应用后     (  e 6  ) 点击“Server”, 将其地址修改为不合法地址“123456” (   e 113
                   e 115  ), 然后点击“REFRESH”按钮  e 124  ), 程序崩溃.
                 到                          (
                    在对应用代码分析后, 我们发现序列            (a) 是因为事件   e 47  点击返回操作, 应用本应该回到欢迎界面          s 0  , 但却错
                                           s 6  , 这是典型的生命周期回调函数处理不当造成的崩溃错误. 而序列                 (b) 则是因
                 误地进入了之前未被销毁的主页
                      e 114  将获取新闻来源的服务器地址设置成了非法格式“123456”导致程序出错.
                 为事件
                    若以传统的测试序列仅考虑           GUI 界面变化的约减方法对序列          (a)、(b) 显然不合适, 例如序列     (a) 中导致程序
                          e 47  在界面上没有导致任何变化. 此外, 通过对动机示例序列的分析, 可知合适的抽象粒度的选择对于
                 崩溃的事件
                 提升序列约减效率也很重要, 例如仅在            Activity  层次上对程序状态进行抽象, 则状态        s 8  、  s 9  会被合并, 但显然这两
                 个状态之间的变化对于崩溃能否被触发非常关键.
                    因此, 如何能够准确、快速地找出对触发程序崩溃起作用的重要事件, 对于提升测试序列约减效率非常重要,
                 这也启发我们结合安卓系统的生命周期管理机制对可能会导致返回栈顺序出错的事件进行识别, 并结合程序静态
                 分析找出与出错函数有数据依赖关系的事件, 最后, 我们采用了多粒度结合的方式, 分别在控件及页面布局粒度上
                 对程序执行状态进行抽象.
   103   104   105   106   107   108   109   110   111   112   113