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

郝蕊 等: 基于事件标记的多粒度结合安卓测试序列约减                                                      2007


                                                                                          [7]
                                                                               [6]
                                                                                                      [8]
                 用质量与安全, 目前学术界及工业界发布了很多自动化测试工具, 例如                      Monkey 、GUIRipper 、DynoDroid 、
                         [9]
                 SwiftHand 、Sapienz [10] 、Stoat  [11] 等, 它们通过采用随机化、模型化、系统化等不同搜索策略对应用进行功能测
                 试, 并生成崩溃测试报告、崩溃测试序列、截图等, 方便开发者进行缺陷回放、理解与修复. 但测试工具生成的复
                 现测试序列往往过长, 包括很多对触发程序崩溃无用的冗余事件                     [12−14] , 使得开发者在进行程序回放、理解与修复
                 时无法快速准确地找到触发程序崩溃的关键事件.
                    测试序列约减      (或测试输入约减) 是解决自动化测试工具生成测试序列过长问题的一种有效手段, 其中增量
                 测试  [15] 是测试输入约减领域最早的经典算法之一, 但由于其采用随机搜索策略, 导致其生成的测试输入存在很多
                 “非法约减”, 例如在安卓测试领域, 其生成的测试序列中的测试事件无法点击到有效控件. 后续研究工作者                               [16−19] 结
                 合安卓测试特点, 通过分析测试过程中应用              GUI 状态变化对测试序列构建树结构或图结构模型, 并在模型基础上
                 进行测试序列约减, 大大提升了约减效率.
                    但目前的测试序列约减仍存在几个问题. 首先, 目前测试序列约减工作仅在单一粒度上对应用界面状态进行
                 抽象, 例如  Jiang  等人  [16] 的工作  SimplyDroid  在活动粒度抽象, 只关注界面  Activity  名称是否变化, Sui 等人  [18] 提出
                 的  ECHO  则在控件粒度抽象, 包括了页面控件及其属性的所有变化. 抽象粒度越低, 其关注的变化就会越细微, 导
                 致序列约减时无法去除一些会造成界面变化但对触发程序崩溃无用的“次要事件”, 但抽象粒度太粗糙则会导致事
                 件之间无法有效区分, 搜索空间过大, 约减时间过长. 此外, 目前测试序列约减工作仅关注应用                           GUI 状态变化, 忽
                 略了测试事件导致的程序内部状态变化, 比如测试事件对程序某些设置变量的改变造成程序崩溃, 这些事件虽然
                 没有造成界面变化, 但却属于约减中需要关注的“重要事件”. 最后, 目前测试序列约减工作的评估只是在简单场景

                 下进行, 缺少对程序间调用、设备网络状态改变、用户输入等复杂交互的支持与分析.
                    针对以上问题, 我们提出了基于事件标记的多粒度结合测试序列约减方法, 在控件粒度、页面布局粒度对比
                 分析程序执行状态并构建模型, 分别进行粗筛选与细约减工作, 此外, 通过结合安卓系统生命周期管理机制、程序
                 静态数据流分析技术, 我们对测试序列中的关键事件进行识别标记, 缩小序列搜索空间, 提升约减效率. 最后, 我们
                 收集了来自安卓应用的        66  个崩溃测试序列, 其包含了程序切换、设备状态改变、用户输入等复杂交互场景, 评估
                 结果验证了我们方法的有效性.
                    本文第   1  节介绍测试序列约减的相关方法和研究现状. 第               2  节介绍本文的动机示例. 第      3  节介绍本文的测试
                 序列约减方法. 第     4  节介绍实验设置与结果讨论. 最后第         5  节对全文进行总结.

                 1   测试序列约减相关工作

                    增量测试是解决测试输入约减问题的一个经典算法                   [15] , 其主要思想是不断迭代简化、验证测试输入, 直至找
                 到触发崩溃的最小输入集合, 但由于其对所有输入一视同仁, 采用随机策略选取待验证输入, 导致其生成很多语义
                 不可行的测试输入, 效率低下, 后续研究工作者们通过对程序输入结构进行分析, 采用层次化方式                            [20] 、树形结构  [21]
                 对测试输入建模, 并设计相关约减算法以提升效率.
                    此外, 不同编程语言、不同系统的测试输入特性不尽相同, 有很多工作就是结合测试输入特性设计约减算法,
                 Regehr 等人  [22] 提出了针对  C  语言编译器测试用例约减方法, 为了解决传统的增量测试约减算法产生很多过长或
                 者无意义的测试用例       (编译无法通过) 的问题, 他们将定义了测试用例有效性验证, 并结合                   C  语言特性提出了     3  种
                 新的测试用例约减器. 基于模型的测试能够依照测试模型生成大量测试用例集, 从而提高测试覆盖率, 但也会导致
                 生成的测试用例过长, 给故障定位带来挑战, 针对这个问题, Kanstrén               等人  [23] 提出了针对模型测试的用例约减, 他
                 们不断生成出错序列的变异体, 并对变异体进行模式挖掘以辅助故障定位. 针对                          JavaScript 应用程序中测试用例
                 的回放约减, Wang    等人  [24] 利用测试用例中事件的变量使用信息构建事件上下文, 并要求约减后测试用例中的事
                 件上下文与原始事件上下文保持一致, 以避免生成语法不可行的子事件序列. 在传统增量测试中, 每删除测试输入
                 中的一个子输入集, 就可能导致需要对所有已经访问过的子输入集再次重验证, 对于大输入集, 这会造成巨大开
                 销, 为了消除这种重新访问, Gharachorlu     等人  [25] 提出了测试输入减少的     3  个独立条件: 公共依赖顺序、无歧义性、
   102   103   104   105   106   107   108   109   110   111   112